LLM推理和優化(1):基本概念介紹

在這里插入圖片描述

一、LLM推理的核心過程:自回歸生成

LLM(如DeepSeek、ChatGPT、LLaMA系列等)的推理本質是自回歸生成:從初始輸入(如[CLS]或用戶prompt)開始,逐token預測下一個詞,直到生成結束符(如[EOS])。其核心分為兩個階段:

1. Initialization階段(初始化)
  • 目標:準備第一個token的生成條件。
  • 關鍵步驟
    • 輸入編碼:將初始prompt轉換為token序列(如[CLS]你好),嵌入為向量x_0
    • 初始隱藏狀態:通過Transformer的編碼器(或直接使用預訓練參數)生成第一層的隱藏狀態h_0
    • KV Cache初始化:為每一層的每個注意力頭創建空的Key/Value緩存(形狀:[batch, heads, seq_len, head_dim])。此時seq_len=0,因為尚無歷史token。

示例:生成首詞“今天”時,輸入為[CLS],初始化后僅計算第一層的h_0,KV Cache為空。

在LLM推理中,Initialization階段(初始化階段)又稱“預填充階段”(Prefill Stage)。這一命名源于其核心功能:為后續的逐token生成預填充(Prefill)KV Cache和初始隱藏狀態

工程實現

Hugging Face的transformers庫、NVIDIA的FasterTransformer均采用prefillgeneration區分這兩個階段。例如:

# 偽代碼:Hugging Face生成邏輯
outputs = model.prefill(prompt)  # 預填充KV Cache(Initialization)
for _ in range(max_new_tokens):outputs = model.generate_step(outputs)  # 解碼階段,逐token生成
術語對比:Initialization vs Prefill
場景常用術語含義側重
學術描述Initialization強調“初始化隱藏狀態和緩存”
工程實踐Prefill強調“預填充固定長度的輸入”
用戶視角輸入處理階段對應“用戶輸入的prompt處理”

本質是同一階段,但“Prefill”更直觀反映了其“為生成提前準備歷史KV”的工程目標。

2. Decoding階段(解碼)
  • 目標:逐token生成,每步復用歷史計算結果
  • 核心邏輯(以生成第t個token為例):
    1. 當前token處理:將第t-1步生成的token嵌入x_t,與前一步隱藏狀態拼接,輸入Transformer層。
    2. 注意力計算優化
      • 查詢(Query):僅計算當前token的Query向量Q_t(因為只關注當前位置)。
      • 鍵值(Key/Value)復用KV Cache中的歷史Key/Value,并追加當前token的Key_t、Value_t。
      • 注意力得分:計算Q_t與所有歷史Key的相似度(僅需一次矩陣乘法,而非重復全量計算)。
    3. 更新KV Cache:將當前層的Key_t、Value_t追加到緩存中(seq_len += 1)。
    4. 生成概率:通過LM頭輸出第t個token的概率分布,選擇下一詞(貪心/采樣)。
3. 舉個栗子🌰
  • 輸入:用戶prompt“請寫一首詩:”(4個token)。
  • Prefill階段
    1. 計算這4個token的所有層Key/Value,填充到KV Cache(此時緩存長度=4)。
    2. 生成第一個待擴展的隱藏狀態(對應第4個token的輸出)。
  • Decoding階段
    逐句生成詩句,每步:
    1. 計算當前token的Q(僅1個token)。
    2. 復用Prefill的4個KV + 之前生成的KV,計算注意力。
    3. 追加當前token的KV到緩存(緩存長度逐步增加到4+N)。

通過“預填充”,避免了每次生成新token時重復計算prompt的KV,這正是LLM實現高效推理的關鍵優化之一。

二、原始Transformer的效率瓶頸:O(n2)的重復計算

  • 時間復雜度:訓練時并行計算所有token的注意力(O(n2)),但推理時需自回歸生成,每步需重新計算所有歷史token的Key/Value,導致總復雜度為O(n3)(n為序列長度)。
  • 空間復雜度:每次推理需保存所有中間層的Key/Value,內存占用隨n線性增長,長文本(如n=4k)時顯存爆炸。
  • 現實痛點:生成1000字的文章需重復計算百萬次注意力,傳統Transformer無法支持實時交互。

三、KV Cache:用空間換時間的核心優化

1. 方法本質

緩存歷史層的Key/Value,避免重復計算。每個Transformer層維護獨立的KV Cache,存儲該層所有已生成token的Key/Value向量。

2. 具體實現步驟(以單batch為例)
  1. 初始化緩存(t=0):

    • 每層創建空緩存:K_cache = [], V_cache = [](形狀:[num_layers, heads, 0, head_dim])。
  2. 第t步生成(t≥1):

    • 前向傳播:輸入當前token嵌入,通過Transformer層計算當前層的Q_t, K_t, V_t
    • 拼接緩存
      K_cache[t_layer] = torch.cat([K_cache[t_layer], K_t], dim=2)  # 在seq_len維度追加
      V_cache[t_layer] = torch.cat([V_cache[t_layer], V_t], dim=2)
      
    • 注意力計算
      attn_scores = Q_t @ K_cache[t_layer].transpose(-2, -1)  # Q_t: [1, heads, 1, d], K_cache: [1, heads, t, d]
      attn_probs = softmax(attn_scores / sqrt(d)) @ V_cache[t_layer]  # 僅需O(t)計算
      
    • 更新隱藏狀態:將注意力輸出傳入下一層,直到LM頭生成token。
  3. 循環:重復步驟2,直到生成[EOS]或達到最大長度。

3. 優化效果
  • 時間:每步注意力從O(n2)→O(n),總復雜度O(n2)(接近線性)。
  • 空間:緩存占用O(n)(每層存儲歷史K/V),但避免了重復計算的中間變量,實際顯存節省50%+。
  • 典型案例:LLaMA-2 70B在4k序列長度下,KV Cache使推理速度提升4倍(NVIDIA官方數據)。

四、延伸:KV Cache的局限性與改進

  • 顯存瓶頸:長上下文(如100k token)的KV Cache占用巨大(每層約4k token×4byte×2(KV)≈32KB,64層×100k≈2GB)。
  • 優化方向
    • 分頁緩存(Paged Attention):NVIDIA提出,用非連續內存存儲KV,減少碎片化(2023年突破)。
    • 動態緩存:僅保留最近相關token的KV(如檢索增強LLM)。

KV Cache是LLM落地的基石,其設計思想(復用歷史計算)貫穿現代推理優化(如FlashAttention、QLoRA),最終實現了從“實驗室模型”到“實時對話”的跨越。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/72025.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/72025.shtml
英文地址,請注明出處:http://en.pswp.cn/web/72025.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【從零開始學習計算機科學】編譯原理(一)編譯過程概述

【從零開始學習計算機科學】編譯原理(一)編譯過程概述 緒論編譯過程概述詞法分析語法分析代碼優化代碼生成其他功能編譯器的前端和后端緒論 什么叫編譯程序?為什么我們需要編譯程序?編譯程序就是一個程序,將便于人編寫、閱讀、維護的高級計算機語言所寫作的源代碼程序,翻…

3-001:MySQL 中的回表是什么?

1. 什么是回表? 回表(Back to Table) 指的是 在使用非聚簇索引(輔助索引)查詢時,MySQL 需要 先通過索引找到主鍵 ID,然后再回到主鍵索引(聚簇索引)查詢完整數據&#xf…

【AIGC】計算機視覺-YOLO系列家族

YOLO系列家族 (1)YOLO發展史(2) YOLOX(3) YOLOv6(4) YOLOv7(5) YOLOv8(6) YOLOv9(7)YOLOv10(8&…

基于Python懂車帝汽車數據分析平臺(源碼+lw+部署文檔+講解),源碼可白嫖!

摘要 時代在飛速進步,每個行業都在努力發展現在先進技術,通過這些先進的技術來提高自己的水平和優勢,汽車數據分析平臺當然不能排除在外。本次我所開發的懂車帝汽車數據分析平臺是在實際應用和軟件工程的開發原理之上,運用Python…

Prompt 工程

一、提示原則 import openai import os import openai from dotenv import load_dotenv, find_dotenv from openai import OpenAI def get_openai_key():_ load_dotenv(find_dotenv())return os.environ[OPENAI_API_KEY]client OpenAI(api_keyget_openai_key(), # This is …

MySQL -- 數據庫基礎

1、基礎登錄操作 mysql 指定選項 選項&#xff1a; <1> -h 指定ip地址&#xff0c;即連接的主機&#xff0c;不帶時&#xff0c;默認連本機 <2> -P 指定的端口號&#xff0c;指定默認端口號&#xff08;配置文件中進行配置&#xff09; <3>-u 指定的用戶 &l…

02C#基本結構篇(D3_內部類-代碼塊-數據類型-變量-常量-字面量-運算符-流程控制語句)

目錄 一、內部類 1. 定義內部類 2. 創建內部類的實例 3. 訪問外部類的私有成員 4. 內部靜態類 5. 使用場景和優點 6. 注意事項 ------------------------------------------- 二、代碼塊 1. 控制流語句 1.1. 條件語句 1> if 語句 2> switch 語句 1.2. 循環語…

15 | 定義簡潔架構 Store 層的數據類型

提示&#xff1a; 所有體系課見專欄&#xff1a;Go 項目開發極速入門實戰課&#xff1b;歡迎加入 云原生 AI 實戰 星球&#xff0c;12 高質量體系課、20 高質量實戰項目助你在 AI 時代建立技術競爭力&#xff08;聚焦于 Go、云原生、AI Infra&#xff09;&#xff1b;本節課最終…

CSDN統計個人創作總字數

前言 不是很懂爬蟲&#xff0c;所以就叫deepseek寫了一個 用起來很簡單&#xff0c;但是有一個小問題&#xff0c;就是統計的是總字符數。代碼片會被統計進去&#xff0c;Markdown語法也會被統計進去。 不過我沒有太多需求&#xff0c;能大概統計一下滿足以下小小的好奇心和成…

React.js 基礎與進階教程

React.js 基礎與進階教程 React.js 是由 Facebook 開發的流行前端 JavaScript 庫&#xff0c;專為構建用戶界面&#xff08;UI&#xff09;設計&#xff0c;尤其適用于單頁面應用&#xff08;SPA&#xff09;。它采用組件化開發模式&#xff0c;使 UI 結構更加清晰、可維護性更…

msf(Metasploit)中Session與Channel的區別與關系解析

在 Metasploit Framework&#xff08;MSF&#xff09;中&#xff0c;Session 和 Channel 都是與目標主機的交互方式&#xff0c;但它們的作用和概念有所不同。本文將解析這兩個術語的區別。 一、Session&#xff08;會話&#xff09; Session 是指通過 Metasploit 成功利用目標…

設計模式-結構型模式-裝飾器模式

概述 裝飾器模式 : Decorator Pattern : 是一種結構型設計模式. 作用 &#xff1a; 允許你動態地給對象添加功能或職責&#xff0c;而無需修改其原始類的代碼,非常的符合 開閉原則。 實現思路 &#xff1a;通過創建一個包裝對象&#xff08;即裝飾器&#xff09;&#xff0c;來…

Qt/C++音視頻開發82-系統音量值獲取和設置/音量大小/靜音

一、前言 在音視頻開發中&#xff0c;音量的控制分兩塊&#xff0c;一個是控制播放器本身的音量&#xff0c;絕大部分場景都是需要控制這個&#xff0c;這個不會影響系統音量的設置。還有一種場景是需要控制系統的音量&#xff0c;因為播放器本身的音量是在系統音量的基礎上控…

基于深度學習的醫學CT圖像肺結節智能檢測與語音提示系統【python源碼+Pyqt5界面+數據集+訓練代碼】

《------往期經典推薦------》 一、AI應用軟件開發實戰專欄【鏈接】 項目名稱項目名稱1.【人臉識別與管理系統開發】2.【車牌識別與自動收費管理系統開發】3.【手勢識別系統開發】4.【人臉面部活體檢測系統開發】5.【圖片風格快速遷移軟件開發】6.【人臉表表情識別系統】7.【…

前端小食堂 | Day14 - Vue 3 の傳送門與懸念

&#x1f300; 今日秘技&#xff1a;Teleport 與 Suspense の時空魔法 1. Teleport 任意門 <template> <!-- &#x1f6aa; 將組件傳送到 body 末尾 --> <Teleport to"body"> <div class"modal"> <h2>重要通知&#x…

emacs使用mongosh的方便工具發布

github項目地址: GitHub - csfreebird/emacs_mongosh: 在emacs中使用mongosh快速登錄mongodb數據庫 * 用途 在emacs中使用mongosh快速登錄mongodb數據庫&#xff0c; 操作方法: M-x mongosh, 輸入數據庫名稱&#xff0c;然后就可以自動登錄&#xff0c;前提是你已經配置好了…

Linux:Ubuntu server 24.02 上搭建 ollama + dify

一、安裝Ubuntu 具體的安裝過程可以參見此鏈接&#xff1a;鏈接&#xff1a;Ubuntu Server 20.04詳細安裝教程&#xff0c;這里主要記錄一下過程中遇到的問題。 安裝時subnet如何填寫 在Ubuntu中subnet填寫255.255.255.0是錯誤的&#xff0c;其格式為 xx.xx.xx.xx/yy &#…

unordered_set 的常用函數

在 C 的標準庫中&#xff0c;std::unordered_set 是基于哈希表實現的哈希集合。下面介紹這種語言里哈希集合的常用函數。 C std::unordered_set 1. 元素操作 insert 功能&#xff1a;向哈希集合中插入元素。如果元素已經存在&#xff0c;則不會重復插入。示例代碼&#xff1a…

starrocks批量啟停腳本

#!/bin/bash # 定義 StarRocks 安裝目錄 STARROCKS_HOME"/path/to/starrocks" # 定義 FE 和 BE 節點列表 FE_NODES("fe_node1_ip" "fe_node2_ip" "fe_node3_ip") BE_NODES("be_node1_ip" "be_node2_ip" "be_…

python 提取視頻中的音頻

在Python中提取視頻中的音頻&#xff0c;你可以使用moviepy庫&#xff0c;這是一個非常強大且易于使用的庫&#xff0c;專門用于視頻編輯。以下是如何使用moviepy來提取視頻中的音頻的步驟&#xff1a; 安裝moviepy 首先&#xff0c;你需要安裝moviepy。你可以通過pip安裝它&a…