<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

LLMEngine下一層級的模塊內如何實現各自功能接口

jf_pmFSk4VX ? 來源:GiantPandaCV ? 2023-08-21 09:45 ? 次閱讀

最近業余時間在看新番vLLM,在讀源碼過程中,對其顯存管理原理有了清晰的認識。vLLM系統主要是基于python+cuda實現的,很多其他python項目實現都很混亂(各種重復代碼、語意不明/模糊的抽象設計),但vLLM的系統設計卻特別工整,為怕遺忘,特別開啟本篇,top down的記錄一下vLLM框架結構。

回到vLLM這個項目,vLLM針對GPT類模型推理過程中KVCache這個顯存占用大頭專門設計了block_table,將KVCache分段成多個block存儲在GPU中。一方面,這種設計可以共用beam search多batch之間share prompt sequence(的KVCache),減少顯存占用。另一方面,在gpu顯存和cpu內存間調度這些block,可以在有限的gpu顯存空間下同時推理更大batch的sequence,換句話說,就是盡可能拉滿gpu顯存使用率,提高吞吐。

本篇文章將會按top down的方式介紹整個系統。先總覽整個框架包含的基本類型,包括類型之間的關系、各類職責。然后,針對系統入口LLMEngine,介紹各個類之間如何通過接口互相組織完成推理過程,加深各個類功能的抽象理解。更進一步的,分析LLMEngine下一層級的模塊內如何實現各自功能接口。(后續也會抽時間專門開一篇介紹vLLM中用到的cuda ops源碼,特別是PageAttention部分,敬請期待)

框架概覽

271dae0c-3f2c-11ee-ac96-dac502259ad0.jpg

vLLM類關系圖

整個框架核心的模塊關系如上:

LLMEngine:是整個系統的入口,add_request負責輸入prompt請求,step迭代推理,最終返回LLM生成的結果。其內部組合了一個Scheduler和一組Worker。

Scheduler:在每個推理步調度可處理的Sequence輸入信息,其組合包含了一個BlockSpaceManager

BlockSpaceManager:維護gpu顯存和cpu內存的使用情況,以及Sequence對應Cache的BlockTable信息。

Worker:在每個推理步執行LlamaForCausalLM推理,并返回采樣后結果。除一個LLM模型外,其另一個核心組件是CacheEngine。

CacheEngine:負責執行相關gpu、cpu空間的換入、換出、拷貝等操作。

LLMEngine

275bb2ce-3f2c-11ee-ac96-dac502259ad0.jpg

LLMEngine實現細節

從圖中可以看到,從上到下按先后順序LLMEngine分別進行了__init__、add_request、step。

在構造LLMEngine時,LLMEngine就會調用Worker中的CacheEngine,初始化gpu、cpu空間,計算能容納多少個block。每個block包含block_size個token對應的各層KVCache大小。在后續的組織中都會將Sequence對應的KVCache分成block_size大小的cache block,以方便管理對應block的空間。

add_request接口執行多次,接收多個待處理的prompt,將prompt處理成對應token的Sequence。每個輸入prompt構造一個SequenceGroup, 其中包含了多個重復的Sequence為后續beam search做準備。SequenceGroup會最終保存到Scheduler中,以進行后續的調度。

step執行一個推理步。首先Scheduler會調度一組SequenceGroup和相關信息作為當前推理步的執行輸入,除了輸入外,還會包含當前SequenceGroup所需KVCache的換入換出信息。然后,Worker會將執行一次LLM推理(當然會先執行CacheEngine先準備KVCache)。Worker采樣的輸出結果會再次更新到Scheduler中的SequenceGroup內,以更新其內部的狀態。最后,多次step循環,直到所有prompt對應的SequenceGroup都生成結束。

Scheduler & BlockSpaceManager

Scheduler

Scheduler中包含了三個隊列:waitting、running、swapped。每當新增一個SequenceGroup時,添加至waitting隊列中。

276dd332-3f2c-11ee-ac96-dac502259ad0.jpg

這三個隊列之間的關系如下:

279b5c58-3f2c-11ee-ac96-dac502259ad0.jpg

waitting:等待計算KVCache的SequenceGroup(也就是prompt序列)

running:執行推理的SequenceGroup,會在當前step中作為輸入,一共包含兩類:

prompt:來自waitting,未計算KVCache的SequenceGroup

generate token:計算過KVCache的SequenceGroup,準備生成下一個token

swapped:KVCache暫時換出到cpu內存的SequenceGroup

在每次schedule執行時,會調度幾個隊列之間的SequenceGroup,維護隊列間的狀態,使得當前執行推理盡可能占滿顯存空間。詳細邏輯如上圖中的數字標號順序所示,值得注意的是,通過調度能實現兩種解決顯存不足的策略,一個是換出到cpu中,另一個就是重計算了(只有在SequenceGroup內只有一個Sequence的情況才能使用)。

當SequenceGroup推理新增了token時,update接口會更新一遍SequenceGroup內的狀態。如下圖所示,SequenceGroup內包含一組beam search的seq,每次執行推理的時候,每個seq采樣s次,那么久會生成n*s個生成的token,根據這里面token保留置信度topn個生成結果。下圖所示的結果就是n=4的情況,可以看到topn保留的output里seq1和seq3都來自原始輸入seq1(parent_seq=1),此時需要BlockSpaceManager將原始的seq3釋放(因為保留的output里沒有seq3的輸出),然后從seq1拷貝/fork到seq3,再講新token添加到各個seq中。

27d4af76-3f2c-11ee-ac96-dac502259ad0.jpg

BlockSpaceManager

BlockSpaceManager的功能是管理各個SequenceGroup對應KVCache存儲信息?;仡橪LMEngine提到過的,每個Sequence的KVCache序列會分成多個block_size長度的cache block,每個cache block的位置信息記錄在BlocKspaceManager。如下圖所示,BlockSpaceManager包含一個block_tables,其記錄cache block到gpu顯存或cpu內存物理地址的映射。

27e7fe00-3f2c-11ee-ac96-dac502259ad0.jpg

SequenceGroup剛加入Scheduler的時候并沒有分配cache block空間,第一次進入running的時候需要向BlockSpaceManager申請可用的block空間。如下圖所示,BlockSpaceManager分配block空間是以一個SequenceGroup作為一組輸入,而且默認分配空間的時候,所有SequenceGroup內的token都是一樣的(即是相同的prompt),因此會為所有Sequence都指向同一片cache block區域,該區域被引用數為Sequence數量。

當需要為一個Sequence新增token時,如下圖所示,有兩種情況:

當前cache block空間不足添加新token,則新增cache block。

當前空間足以添加新token,但last block與其他Sequence共用時(ref_count>1),如果新token還是添加到last block,那么會與共用last block的其他Sequence沖突,則需要釋放掉last block(free不是真的釋放,只是ref_count-1),分配一個新的last block。最后,返回信息標記原本last block內容需要拷貝到這個新的last block,即所謂的“copy-on-write”。

28209062-3f2c-11ee-ac96-dac502259ad0.jpg

最后就是BlockSpaceManager其他接口的實現圖解了,詳細可參加下圖:

28547210-3f2c-11ee-ac96-dac502259ad0.jpg

實際上,BlockSpaceManager只負責維護cache block到gpu/cpu空間的索引,真正進行換入、換出、拷貝操作都需要通過Worker中CacheEngine進行。因此在Scheduler調度的時候,也會收集BlockSpaceManager返回結果,得到當前step所需KVCache的block_to_swap_in、block_to_swap_out、block_to_copy,以供后續CacheEngine操作內存空間。

Worker

Worker負責緩存更新執行和LLM推理執行。關于Worker的這個圖比較長,因此這里截斷成兩張圖來看。

2875684e-3f2c-11ee-ac96-dac502259ad0.jpg

如上圖所示,Worker在執行時首先進行兩個操作。

緩存更新:SchedulerOutputs包含了前面提到的當前所需swap in/swap out/copy的cache block信息,然后通過CacheEngine自定義的ops去執行緩存搬運操作,得到cuda stream的event,后續會在推理LLM各層的時候用到。

準備輸入token序列__prepare_input:上圖右側的框內是預處理的過程,將SequenceGroupMetadata包含Scehduler調度得到running的所有SequenceGroup組合一個flatten的token序列,作為LLM的初始輸入。Scheduler那節中提到過,running隊列中當前執行的SequenceGroup有兩類:一類未計算prompt(前綴)的KVCache,這部分需要完整的prompt token輸入去計算各層的KVCache(全量推理)。另一類已經計算并緩存前綴的KVCache,因此只需要last token作為輸入計算下一個generation token的分布(增量推理)。如上圖所示,輸入token序列的前半部分是多個prompt的token全量推理序列,后半部分是各個增量推理序列的last token。此外,全量推理的SequenceGroup中多個Sequence共享prompt,因此只需要任意一個Sequence的prompt作用輸入就行。

289d68d0-3f2c-11ee-ac96-dac502259ad0.jpg

上圖是Worker執行LLM模型的過程。由__prepare_input組裝的flatten token在各層映射成flatten hidden state。除了線性層、激活層等token獨立計算的層以外,attention層的計算涉及不同token的hidden state依賴。上圖主要展開了Attention層的四個主要步驟:

prompt全量推理:prompt序列通過xformers的attention算子計算得到下個layer的hidden state。由于這里attention計算的輸入是完整的tensor,不是KVCache中分散的cache block,所以可以用第三方的attention算子完成計算。

等待緩存事件:CacheEngine中發送了異步緩存操作,因此只有當前層序列的cache block完成緩存更新,才能進一步獲取KVCache或者記錄KVCache,這種異步的實現能通過overlap計算和緩存搬運,節省一部分緩存搬運時間。

記錄當前KVCache:當前層輸入的hidden state作為KVCache通過自定義算子記錄到對應cache block內,這里記錄所有有效token的hidden state,包括prompt和last token(last token是前幾次step中新增的,所以也沒有緩存hidden state到KVCache)。

generation token增量推理:vLLM的核心PageAttention即在此實現,這里作者通過一個自定義算子(好像是參考Faster Transformer實現),實現了基于BlockTable分散KVCache的增量attention計算。

最后LLM內的采樣器進行采樣,將beam_search結果(新token)返回給Worker輸出。

碎碎念

至此,筆者基本完成想要表達的的vLLM top down系統架構,相關的框架drawio已上庫(圖畫的都有點挫,文章里可能不方便看。。),希望這篇文章能幫助有意愿在vLLM上做貢獻的小伙伴。針對vLLM作者設計的cache_ops、attention_ops的自定義實現,筆者也會利用業余時間學習,補一篇文章進行介紹。

審核編輯:彭菁

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 模塊
    +關注

    關注

    7

    文章

    2520

    瀏覽量

    46702
  • 接口
    +關注

    關注

    33

    文章

    7859

    瀏覽量

    148972
  • 模型
    +關注

    關注

    1

    文章

    2790

    瀏覽量

    47916
  • python
    +關注

    關注

    52

    文章

    4698

    瀏覽量

    83610
  • GPT
    GPT
    +關注

    關注

    0

    文章

    326

    瀏覽量

    15015

原文標題:vLLM框架top down概覽

文章出處:【微信號:GiantPandaCV,微信公眾號:GiantPandaCV】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    簇嵌套簇的中控件屬性如何操作

    請問各位大大,我想控制簇嵌套簇中的某個控件的可見屬性應該怎樣做呢?發現可以控制簇的下一層控件的屬性,但是再下一層簇中的控件就不知怎控制了。如圖所示,我想控制讓其中個布爾控件不可見。怎做到?
    發表于 07-06 23:59

    單片機程序設計的十功力,你練到那一層了?

    簡單模塊化,如何合理的利用CPU的時間。我曾經寫過這一層點簡單教程。對付這一層應該是綽綽有余了。第三 并肩作戰,時間,說愛你不容易。
    發表于 11-01 08:50

    控件快捷菜單選擇事件,能不能選擇不是最低一層的菜單?

    圖中控件快捷菜單有3,第一層“3”,第二“3.2”,第三“3.2.1”“3.2.2”,通過事件結構里面的“快捷菜單選擇”只能觸發最后一層
    發表于 04-14 10:06

    單片機程序設計的十功力,你練到那一層了?

    一層 : 我來了處在這一層的典型是可以用C語言寫簡單的邏輯控制,如閃爍LED,簡單數碼管顯示,簡單外圍模塊驅動實驗。般對單片機感興趣,經常動手實踐的人,半年左右,可以練到此地步(針
    發表于 03-22 11:46

    單片機程序設計的十功力,你練到那一層了?

    一層 : 我來了處在這一層的典型是可以用C語言寫簡單的邏輯控制,如閃爍LED,簡單數碼管顯示,簡單外圍模塊驅動實驗。般對單片機感興趣,經常動手實踐的人,半年左右,可以練到此地步(針
    發表于 09-07 10:13

    EPON系統三接口設計

    軟硬件平臺驅動之上,三功能協議及管理之下,是三功能
    發表于 06-06 05:00

    如何添加一層機械?

    請問如何添加一層機械?謝謝
    發表于 09-17 02:56

    文帶你看懂HarmonyOS如何適配多種終端

    接口的同時,隱藏內部實現細節。對于中小規模系統,基于架構分層可以較好地解決系統架構解耦和跨團隊協作問題,每一層提供定的業務功能,可以由不同
    發表于 10-12 14:37

    HFSS Frequency 設置問題

    HFSS 的drien solution frequency 設置的頻率 和下一層的 sweep 里面設置的frequency start stop是什么關系?這兩個分別設置的是什么頻率?
    發表于 11-07 22:53

    AUTOSAR基礎軟件是由哪些部分組成的

    基礎軟件主要是用于提供基礎軟件服務,包括標準化的系統功能以及功能接口,并且由系列的基礎服務軟件組成,包括系統服務、內存服務、通信服務等。
    發表于 02-17 08:00

    基于RT-Thread內核的AUTOSAR在n32g上的實現方案

    服務、ECU抽象、MCU抽象,分層的目的是為了實現各層的復用和對下一層的隔離,這正如RT-Thread的分層思想那樣,RT-Threa
    發表于 07-27 14:30

    用Verilog/SystemVerilog快速實現個加法樹

    reduceBalancedTree提供了兩個方法調用:Vec類型和Seq類型均可以調用該方法,該方法實現為:從源代碼里可以看出,該方法最終的實現依賴兩個參數:op: (T, T) => T 樹的每一層級的操作,上面
    發表于 08-01 14:29

    STM32F1 LWIP開發手冊

    了電子設備如何連入因特網,以及數據如何在它們之間傳輸的標準。協議采用了4層級結構,每一層都呼叫它的下一層所提供的協議來完成自己的需求。通俗而言:TCP負責發現傳輸的問題,
    發表于 09-27 08:23

    嵌入式多功能接口轉換器的設計與實現

    本文研究如何在嵌入式開發平臺上構建一臺多功能接口轉換器。使得不同接口的智能設備能通過該接口轉換器實現數據統一由網絡接口傳送到計算機。并在AR
    發表于 07-01 17:04 ?24次下載

    什么是type-c全功能接口 Type-C充電接口和type-c全功能接口有什么不同

    Type-C全功能接口,也被稱為USB-C全功能接口,是一種多功能的連接接口標準。它是由USB Implementers Forum(USB-IF)制定的一種標準,并在現代設備中被廣泛
    的頭像 發表于 08-03 14:32 ?3w次閱讀
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>