TGI 基準測試

HuggingFace發表於2024-06-25

本文主要探討 TGI 的小兄弟 - TGI 基準測試工具。它能幫助我們超越簡單的吞吐量指標,對 TGI 進行更全面的效能剖析,以更好地瞭解如何根據實際需求對服務進行調優並按需作出最佳的權衡及決策。如果你曾覺得 LLM 服務部署成本太高,或者你想對部署進行調優,那麼本文很適合你!

我將向大家展示如何輕鬆透過 Hugging Face 空間 進行服務效能剖析。你可以把獲得的分析結果用於 推理端點 或其他相同硬體的平臺的部署。

動機

為了更好地理解效能剖析的必要性,我們先討論一些背景資訊。

大語言模型 (LLM) 從根子上來說效率就比較低,這主要源自其基於 解碼器的工作方式,每次前向傳播只能生成一個新詞元。隨著 LLM 規模的擴大以及企業 採用率的激增,AI 行業圍繞最佳化手段創新以及效能提優技術做了非常出色的工作。

在 LLM 推理服務最佳化的各個方面,業界積累了數十項改進技術。各種技術層出不窮,如: Flash AttentionPaged Attention流式響應批處理改進投機解碼、各種各樣的 量化 技術、前端網路服務改進,使用 更快的語言 (抱歉,Python 🐍!) 等等。另外還有不少用例層面的改進,如 結構化生成 以及 水印 等都在當今的 LLM 推理世界中佔據了一席之地。我們深深知道,LLM 推理服務最佳化沒有萬能靈丹,一個快速高效的推理服務需要整合越來越多的細分技術 \(^{[1]}\)

TGI 是 Hugging Face 的高效能 LLM 推理服務,其宗旨就是擁抱、整合、開發那些可用於最佳化 LLM 部署和使用的最新技術。由於 Hugging Face 的強大的開源生態,大多數 (即使不是全部) 主要開源 LLM 甫一發布即可以在 TGI 中使用。

一般來講,實際應用的不同會導致使用者需求迥異。以 RAG 應用 的提示和生成為例:

  • 指令/格式
    • 通常很短,<200 個詞元
  • 使用者查詢
    • 通常很短,<200 個詞元
  • 多文件
    • 中等大小,每文件 500-1000 個詞元,
    • 文件個數為 N,且 N<10
  • 響應
    • 中等長度 , ~500-1000 個詞元

在 RAG 應用中,將正確的文件包含於提示中對於獲得高質量的響應非常重要,使用者可以透過包含更多文件 (即增加 N) 來提高這種機率。也就是說,RAG 應用通常會嘗試最大化 LLM 的上下文視窗以提高任務效能。而一般的聊天應用則相反,典型 聊天場景 的詞元比 RAG 少得多:

  • 多輪對話
    • 2xTx50-200 詞元,T 輪
    • 2x 的意思是每輪包括一次使用者輸入和一次助理輸出

鑑於應用場景如此多樣,我們應確保根據場景需求來相應配置我們的 LLM 服務。為此,Hugging Face 提供了一個 基準測試工具,以幫助我們探索哪些配置更適合目標應用場景。下文,我將解釋如何在 Hugging Face 空間 上使用該基準測試工具。

Pre-requisites

在深入研究基準測試工具之前,我們先對齊一下關鍵概念。

延遲與吞吐

圖 1: 延遲與吞吐量的視覺化解釋

圖 1: 延遲與吞吐量的視覺化解釋

  • 詞元延遲 – 生成一個詞元並將其返回給使用者所需的時間
  • 請求延遲 – 完全響應請求所需的時間
  • 首詞元延遲 - 從請求傳送到第一個詞元返回給使用者的時間。這是處理預填充輸入的時間和生成第一個詞元的時間的和
  • 吞吐量 – 給定時間內服務返回的詞元數 (在本例中,吞吐量為每秒 4 個詞元)

延遲是一個比較微妙的測量指標,它無法反應全部情況。你的生成延遲可能比較長也可能比較短,但長也好短也罷,並不能完整刻畫實際的服務效能。

我們需要知道的重要事實是: 吞吐和延遲是相互正交的測量指標,我們可以透過適當的服務配置,針對其中之一進行最佳化。我們的基準測試工具可以對測量資料進行視覺化,從而幫助大家理解折衷之道。

預填充與解碼

圖 2: 預填充與解碼圖解,靈感來源

圖 2: 預填充與解碼圖解,靈感來源 \(^{[2]}\)

以上給出了 LLM 如何生成文字的簡圖。一般,模型每次前向傳播生成一個詞元。在 預填充階段 (用橙色表示),模型會收到完整的提示 (What is the capital of the US?) 並依此生成首個詞元 (Washington)。在 解碼階段 (用藍色表示),先前生成的詞元被新增進輸入 (What is the capital of the US? Washington),並饋送給模型以進行新一輪前向傳播。如此往復: 向模型饋送輸入 -> 生成詞元 -> 將詞元新增進輸入,直至生成序列結束詞元 ()。


思考題: 為何預填充階段我們饋送了很多詞元作為輸入,卻僅需做一輪前向?
點選揭曉答案 因為我們無需生成 “What is the” 的下一個詞元,我們已經知道它是 “capital” 了。

為了易於說明,上圖僅選擇了一個短文字生成示例,但注意,預填充僅需要模型進行一次前向傳播,但解碼可能需要數百次或更多的前向傳播,即使在上述短文字示例中,我們也可以藍色箭頭多於橙色箭頭。我們現在可以明白為什麼要花這麼多時間才能等到 LLM 的輸出了!由於前向次數較多,解碼階段通常是我們花心思更多的地方。

基準測試工具

動機

在對工具、新演算法或模型進行比較時,吞吐量是大家常用的指標。雖然這是 LLM 推理故事的重要組成部分,但單靠吞吐量還是缺少一些關鍵資訊。一般來講,我們至少需要知道吞吐量和延遲兩個指標才能作出正確的決策 (當然你增加更多指標,以進行更深入的研究)。TGI 基準測試工具就支援你同時得到延遲和吞吐量兩個指標。

另一個重要的考量是你希望使用者擁有什麼體驗。你更關心為許多使用者提供服務,還是希望每個使用者在使用你的系統後都能得到快速響應?你想要更快的首詞元延遲 (TTFT,Time To First Token),還是你能接受首詞元延遲,但希望後續詞元的速度要快?

下表列出了對應於不同目標的不同關注點。請記住,天下沒有免費的午餐。但只要有足夠的 GPU 和適當的配置,“居天下有甚難”?

我關心 ...... 我應專注於 ......
處理更多的使用者 最大化吞吐量
我的網頁/應用正在流失使用者 最小化 TTFT
中等體量使用者的使用者體驗 最小化延遲
全面的使用者體驗 在給定延遲內最大化吞吐量

環境搭建

基準測試工具是隨著 TGI 一起安裝的,但你需要先啟動服務才能執行它。為了簡單起見,我設計了一個空間 - derek-thomas/tgi-benchmark-space,其把 TGI docker 映象 (固定使用最新版) 和一個 jupyter lab 工作空間組合起來,從而允許我們部署選定的模型,並透過命令列輕鬆執行基準測試工具。這個空間是可複製的,所以如果它休眠了,請不要驚慌,複製一個到你的名下就可以了。我還在空間裡新增了一些 notebook,你可以參照它們輕鬆操作。如果你想對 Dockerfile 進行調整,請隨意研究,以瞭解其構建方式。

起步

請注意,由於其互動性,在 jupyter lab 終端中執行基準測試工具比在 notebook 中執行要好得多,但我還是把命令放在 notebook 中,這樣易於註釋,並且很容易照著做。

  1. 點選 “Duplicate this space” 按鈕
  • 空間密令 中設定你自己的 JUPYTER_TOKEN 預設密碼 (系統應該會在你複製空間時提示你)
  • 選擇硬體,注意它應與你的最終部署硬體相同或相似
  1. 進入你的空間並使用密碼登入
  2. 啟動 01_1_TGI-launcher.ipynb
  • 其會用 jupyter notebook 以預設設定啟動 TGI
  1. 啟動 01_2_TGI-benchmark.ipynb
  • 其會按照指定設定啟動 TGI 基準測試工具

主要區塊

圖 3:基準測試報告區塊

圖 3:基準測試報告區塊

  • 區塊 1: batch size 選項卡及其他資訊。
    • 使用箭頭選擇不同的 batch size
  • 區塊 2區塊 4: 預填充/解碼階段的統計資訊及直方圖
    • 基於 --runs 的數量計算的統計資料/直方圖
  • 區塊 3區塊 5: 預填充/解碼階段的 延遲 - 吞吐量 散點圖
    • X 軸是延遲 (越小越好)
    • Y 軸是吞吐量 (越大越好)
    • 圖例是 batch size
    • 理想 ”點位於左上角 (低延遲、高吞吐)

理解基準測試工具

圖 4:基準測試工具散點圖

圖 4:基準測試工具散點圖

如果你的硬體和設定與我相同,應該會得到與圖 4 類似的圖。基準測試工具向我們展示了: 在當前設定和硬體下,不同 batch size (代表使用者請求數,與我們啟動 TGI 時使用的術語略有不同) 下的吞吐量和延遲。理解這一點很重要,因為我們應該根據基準測試工具的結果來調整 TGI 的啟動設定。

如果我們的應用像 RAG 那樣預填充較長的話, 區塊 3 的圖往往會更有用。因為,上下文長度的確會影響 TTFT (即 X 軸),而 TTFT 是使用者體驗的重要組成部分。請記住,雖然在預填充階段我們必須從頭開始構建 KV 快取,但好處是所有輸入詞元的處理可以在一次前向傳播中完成。因此,在許多情況下,就每詞元延遲而言,預填充確實比解碼更快。

區塊 5 中的圖對應於解碼階段。我們看一下資料點的形狀,可以看到,當 batch size 處於 1~32 的範圍時,形狀基本是垂直的,大約為 5.3 秒。這種狀態就相當不錯,因為這意味著在不降低延遲的情況下,我們可以顯著提高吞吐量!64 和 128 會怎麼樣呢?我們可以看到,雖然吞吐量在增加,但延遲也開始增加了,也就是說出現了折衷。

對於同樣的 batch size,我們再看看 區塊 3 圖的表現。對 batch size 32,我們可以看到 TTFT 的時間仍然約為 1 秒。但我們也看到從 32 -> 64 -> 128 延遲出現了線性增長,2 倍的 batch size 的延遲也是 2 倍。此外,沒有吞吐量增益!這意味著我們並沒有真正從這種折衷中獲得太多好處。


思考題:
  • 如果新增更多的資料點,你覺得其形狀會如何呢?
  • 如果詞元數增加,你舉得這些散點 (預填充抑或解碼) 的形狀會如何變化呢?

如果你的 batch size 落在垂直區,很好,你可以獲得更多的吞吐量並免費處理更多的使用者。如果你的 batch size 處於水平區,這意味著你受到算力的限制,每增加一個使用者都會損害每個人的延遲,且不會帶來任何吞吐量的好處。你應該最佳化你的 TGI 配置或擴充套件你的硬體。

現在我們已經瞭解了 TGI 在各種場景中的行為,我們可以多嘗試幾個不同的 TGI 設定並對其進行基準測試。在選定一個好的配置之前,最好先多試幾次。如果大家有興趣的話,或許我們可以寫個續篇,深入探討針對聊天或 RAG 等不同用例的最佳化。

尾聲

追蹤實際使用者的行為非常重要。當我們估計使用者行為時,我們必須從某個地方開始並作出有根據的猜測。這些數字的選擇將對我們的剖析質量有重大影響。幸運的是,TGI 會在日誌中告訴我們這些資訊,所以請務必檢查日誌。

一旦探索結束,請務必停止執行所有程式,以免產生進一步的費用。

  • 終止 TGI-launcher.ipynb jupyter notebook 中正在執行的單元
  • 在終端中點選 q 以終止執行分析工具
  • 在空間設定中點選暫停

總結

LLM 規模龐大且昂貴,但有多種方法可以降低成本。像 TGI 這樣的 LLM 推理服務已經為我們完成了大部分工作,我們只需善加利用其功能即可。首要工作是瞭解現狀以及你可以做出哪些折衷。透過本文,我們已經瞭解如何使用 TGI 基準測試工具來做到這一點。我們可以獲取這些結果並將其用於 AWS、GCP 或推理終端中的任何同等硬體。

感謝 Nicolas Patry 和 Olivier Dehaene 建立了 TGI 及其 基準測試工具。還要特別感謝 Nicholas Patry、Moritz Laurer、Nicholas Broad、Diego Maniloff 以及 Erik Rignér 幫忙校對本文。

參考文獻

  • [1]: Sara Hooker, The Hardware Lottery, 2020
  • [2]: Pierre Lienhart, LLM Inference Series: 2. The two-phase process behind LLMs’ responses, 2023

英文原文: https://hf.co/blog/tgi-benchmarking

原文作者: Derek Thomas

譯者: Matrix Yao (姚偉峰),英特爾深度學習工程師,工作方向為 transformer-family 模型在各模態資料上的應用及大規模模型的訓練推理。

相關文章