我們的健康檢查在一天內重啟了八次健康的模型伺服器
維運
7 月 22 日,一個守護程序重啟了我們的本地模型伺服器八次。這八次重啟背後沒有一次是真正的崩潰。原本旨在維持模型運行的檢查機制,反而是導致其停機的原因。
發生了什麼事
該模型伺服器在一台 NVIDIA GB10 機器上執行 vLLM,單一請求的生成速度約為每秒 8 個 token。每五分鐘,守護程序會發送一個真實的聊天請求,並等待最多 45 秒以獲取回應。連續五次檢查失敗代表伺服器掛起,守護程序便會重啟它。重啟過程會使模型離線數分鐘,因為需要重新載入約 19 GB 的權重。
當天,一個批次作業讓伺服器同時處理兩到四個請求,每次持續數分鐘。守護程序的請求排在它們後面等待,最終超時並被計為失敗。經過五次這樣的檢查後,一個健康的伺服器被重啟了。我們有一個守護程序會尊重的「忙碌」標記檔案,但批次作業從未設定它。
一次誤重啟如何引發下一次
每次重啟都會使進行中的請求失敗並返回 500 錯誤(「cannot schedule new futures after shutdown」)。第二個守護程序統計 500 錯誤數量,當錯誤過多時便重啟伺服器,且錯誤越多,它行動得越快。因此,每次誤重啟都會讓下一次重啟來得更早。總共有四個獨立的守護程序可以重啟該伺服器,分別基於 5、10、15 和 30 分鐘的排程器。
我們從中汲取的原則
健康檢查不得使用它所守護的資源。模型伺服器的稀缺資源是處理中請求的槽位。若檢查機制佔用其中一個槽位,或等待一個槽位,它就成為了它本應評估的負載的一部分。請以低成本進行檢查,並且只有在能證明伺服器卡住時才進行重啟。
取代它的檢查機制
vLLM 在 /metrics 發布其自身的計數器。新的檢查機制首先讀取這些數據:
- 執行中的請求與引擎進度:健康且忙碌。不發送測試請求。
- 兩次讀取之間執行中的請求無進度:卡住。這是仍會觸發重啟的情況。
- 無執行中的請求:閒置。只有在這種情況下,檢查機制才會要求一個簡短回應,閒置的引擎會立即給出。
第一個版本將生成的 token 數量視為進度。它通過了八項測試,但在首次實際運行時發現伺服器忙碌且健康:2 個請求執行中,兩次讀取之間新增了 107 個 token。
我們隨後所做的更改
- 計算引擎步驟,而非輸出 token。當 vLLM 讀取長提示詞時,有一段時間不會產生輸出 token,但仍會執行步驟。計算步驟數(即 vllm:iteration_tokens_total 的計數)可避免長提示詞看起來像伺服器卡死。
- 在判定「卡死」前有兩次等待,因此短暫暫停不會被視為失敗。
- 兩次讀取之間的重啟會被偵測到,透過相同指標中的程序啟動時間;檢查接著會要求回應,而不是比較來自兩個不同程序的計數器。
- 代理伺服器僅透過 /models 檢查。在最少連線數代理伺服器後方,每次讀取 /metrics 可能來自不同的後端,正如我們發現的情況:在兩台機器上各執行一份模型副本。後端會直接檢查。
差異顯而易見。撰寫此說明時,我們的兩台模型伺服器各自執行 12 個請求,達到上限。測試請求會排隊等待。新的檢查報告兩者皆忙碌且健康,分別為每秒 126 和 101 個 token,且無需發送請求。
Factory Floor 1.0.2 將此檢查作為 models/llm-health.py 出貨,包含針對閒置、忙碌、卡死和重啟伺服器、無指標伺服器、代理伺服器以及失效後端的測試。