背景
目前在公司內部4張A10的GPU服務器上部署了ChatGLM3開源模型;然後部署了官方默認的web_demo、api_demo兩種模式;重新設計了前端,支持H5和安卓兩個客戶端調用。但卻發現了不能併發訪問的問題。
問題現象
在安卓與H5同時調用ChatGLM的API接口(流式接口)時,其中有一個客戶端的返回是正常的,而另一個客戶端返回卻是亂碼(解碼後是空數據),同時模型報錯。報錯內容與問題請看issue。
官方回覆如下:
後來我測試用多卡部署模型,比如3卡,此時可以支持3個以下的用戶調用,但再多就不行了。
問題分析
由於非AI相關科班出身也不是專門做這個的,因此一下子還有點棘手;後來在智譜AI開放平臺的使用指南-速率限制指南 一文中,發現其支持併發調用,只是說有併發數限制。因此我分析來說,應該是放出來的模型與開放平臺上的模型有一定的區別,而這個區別就在於模型的併發能力。畢竟外部API調用時,最終還是調用模型內部的流式接口/非流式接口。也就是說,這個模型內部的接口並不支持並行計算。
從模型的內部來說,其是transformer神經網絡結構,但其併發能力卻沒有這麼簡單,畢竟模型涉及到的計算量是巨大的。歸根來說,還是transformer的並行計算能力。
後來找到個遇到同樣情況的博文,不過和我們的部署方式還是有區別的。mosec部署chatglm2-6B 一文中分析了下其遇到的問題與解決方案,至此我大概也清楚了併發調用模型API時爲什麼會返回亂碼(空數據)。
原因與解決策略
當併發調用時,其中模型已經處理完了一個request後,返回的tensor識別了eos_token,模型會認爲已經處理完了所有的request,因此返回空數據。
那麼從這裏來說的話,我暫時想到的解決策略:模型內部按batch來處理request。
這個代碼不好改,應該有開源的實現和解決策略。後來我又想到了LLaMA-Factory這個微調框架,他們也是有api_demo的,應該也會遇到這樣的問題,因此提了個Issue,還好最終有另外的解,見issue。
LLaMA-Factory官方通過vllm實現了併發流式,暫時還沒驗證,簡單看了下代碼,理論上是冒得問題的:
首發於個人公衆號