多模態資料處理¶
為了在 vLLM 中實現各種最佳化,例如 分塊預填充 和 字首快取,我們使用 BaseMultiModalProcessor,該處理器根據 HF 處理器的輸出,提供佔位符特徵令牌(例如 `<image>`)與多模態輸入(例如原始輸入影像)之間的對應關係。
以下是 BaseMultiModalProcessor 的主要特性:
提示更新檢測¶
HF 處理器的主要職責之一是更新帶有佔位符令牌的提示。例如:
- 在字串開頭插入特徵佔位符令牌(例如 `<image><image>...<image>`,數量等於特徵大小)。
- 將現有的輸入佔位符令牌(例如單個影像的 `<image>`)替換為特徵佔位符令牌(例如 `<image><image>...<image>`,數量等於特徵大小)。
有關哪些令牌已更新的資訊是查詢佔位符特徵令牌與多模態輸入之間對應關係的關鍵。
在 vLLM 中,此資訊使用 `_get_prompt_updates` 中的 PromptUpdate 來指定。透過檢查更新後的令牌是否存在,我們可以自動檢測 HF 是否已更新提示。
分詞後的提示輸入¶
為了在單獨的程序中進行分詞,我們支援在傳遞多模態資料時一併傳遞輸入令牌 ID。
問題所在¶
考慮到 HF 處理器的主要步驟如下:
- 分詞
- 處理多模態輸入
- 執行提示更新
而我們的要求是:
- 對於文字 + 多模態輸入,應用所有步驟 1-3。
- 對於分詞後的輸入 + 多模態輸入,僅應用步驟 2-3。
如何在不重寫 HF 處理器的情況下實現這一點?我們可以嘗試對不同的輸入多次呼叫 HF 處理器。
- 對於文字 + 多模態輸入,直接呼叫 HF 處理器。
- 對於分詞後的輸入 + 多模態輸入,僅在多模態輸入上呼叫處理器。
雖然 HF 處理器原生支援文字 + 多模態輸入,但對於分詞後的輸入 + 多模態輸入則不是如此:如果輸入佔位符令牌的數量與多模態輸入的數量不匹配,則會丟擲錯誤。
此外,由於分詞後的文字未經過 HF 處理器處理,我們必須自己應用步驟 3,以使輸出令牌和多模態資料保持一致。
佔位符文字¶
我們透過要求每個模型透過 get_dummy_text 定義如何根據多模態輸入的數量生成佔位符文字來解決第一個問題。這使我們能夠生成與多模態輸入對應的佔位符文字,並將它們一起輸入以獲得處理後的多模態資料。
自動提示更新¶
我們透過在 _apply_prompt_updates 中實現與模型無關的程式碼來解決第二個問題,該程式碼根據 _get_prompt_updates 輸出的規範自動使用特徵佔位符令牌更新提示。
摘要¶
在佔位符文字和自動提示更新的幫助下,我們的多模態處理器最終可以同時接受文字和分詞後的提示以及多模態資料。詳細邏輯顯示在 _apply_hf_processor_main 中。
處理器輸出快取¶
一些 HF 處理器,例如 Qwen2-VL 的處理器,非常慢。為了緩解這個問題,我們快取 HF 處理器的多模態輸出,以避免再次處理相同的多模態輸入(例如影像)。
當傳入新資料時,我們首先檢查哪些項在快取中,哪些項缺失。缺失的項將批次傳遞給 HF 處理器進行處理並快取,然後與快取中已有的項合併。
由於我們只處理缺失的多模態資料項,因此輸入佔位符令牌的數量不再與多模態輸入的數量相匹配,所以它們不能與文字提示一起傳遞給 HF 處理器。因此,我們分別處理文字和多模態輸入,使用 佔位符文字 來避免 HF 錯誤。由於這會跳過 HF 的提示更新程式碼,因此我們之後應用 自動提示更新 來使輸出令牌和多模態資料保持一致。