我不會用 Triton 系列:Stateful Model 學習筆記
Stateful Models 學習筆記
在 Triton Architecture 的文件中,有一個令我困惑了許久的 feature:Stateful Models。如果你也看不太懂的話,並且想知道或必須知道它是什麼東西的話,不妨看看這一篇學習筆記,看看能不能對比有所幫助。下面是我的一點粗淺的理解,如果有錯誤,懇請您在評論區指出,謝謝~!
連結:https://github.com/triton-inference-server/server/blob/main/docs/architecture.md#stateful-models
概念辨析
在 Triton 中,什麼是 Stateful Model 呢?
應用場景:“a stateful model does maintain state between inference requests.” 請求和請求之間,儲存了一些狀態,所以你希望可以將一連串的請求 (sequence of requests) 傳送給同一個模型例項,從而使得模型的狀態可以正確的更新。
如果你學習過一些迴圈神經網路模型的話,你可能會說 RNN、LSTM 等模型就是 Stateful Model。沒有錯,這些模型確實是有狀態的,只不過在 Triton 的某些語境下,Stateful Model 指的是 Stateful Backend(比如上面的那句英語)。狀態都是由 Backend 來進行管理的,所以我認為不應該叫 Stateful Model,而應該叫做 Stateful Backend。
將 Stateful Model 叫做 Stateful Backend 是更加合適的,因為一個你不可能去直接匯出一個模型,然後利用現有 pytorch backend,tensorflow backend 去用上這個特性。你要用這個特性,不能只靠匯出 Model,你需要自己開發一個 Backend 才行。
具體來說,為了使用上 sequence batching,你期望可以從客戶端請求那裡拿到是否開始、是否結束、一個 sequence id。對於這些資訊,你需要在 Custom Backend 裡面去獲取出來進行處理,現有提供的幾個常用的 Backend 並沒有這些功能哦。當然你可以使用
使用者的 Model 在這裡扮演一個什麼樣的角色呢?你可以理解這個 Model 的輸入需要狀態向量、資料向量。這些輸入的狀態向量由 Backend 進行保管,在 Backend 裡面,你可以獲取到 Start、End、Ready 三種和 Batch Size 等大的一維向量;你也可以拿到一連串請求 (sequence of requests) 的 request id。
Control Inputs
Triton 有四種控制輸入:Start、End、Ready、Correlation ID。
文件中提到:“The START tensor must be 1-dimensional with size equal to the batch-size.”,後面的 End 和 Ready 也是和 Batch Size 一樣大的一維向量。在 Triton 中,每個例項會開出和 max_batch_size 一樣多的 slot,所以 Start、End、Ready 的大小和 max_batch_size 一樣多,也和一個 model instance 上的 slot 一樣多。
三者的語義分別表示,在對應的 slot 上,是否有一個 request 開始了、結束了、準備好了。對於 Start 和 End,在客戶端做請求的時候,只需要設定 infer 介面中對應的選項即可;對於 Ready,由 Triton 來控制。
對於 Correlation ID,表示一連串請求的 id,這一連串的請求都使用這同一個 id,Backend 需要使用這個 id 來找到區分請求。
例子
以官方文件的圖為例子。在 Backend 中,我們可以拿到 START 和 READY 兩個向量。
- Req0 來了,START 為 [1, 0],表明 Slot0 的請求是一個開始,而 Slot1 不是;READY 為 [1, 0],表明 Slot1 的請求已經準備好了,可以開始推理了。
- Idle。沒有請求,Instance0 休息。
- 第一個序列的 Req1 來了,第二個序列的 Req0 來了。此時 START 為 [0, 1],表明 Slot0 的請求不是開始,而 Slot1 的請求是一個開始;READY 為 [1, 1] 表明兩個請求都已經準備好了,可以組成一個 Batch 做請求了。
- ...(後面的分析相同了,略)
排程策略
direct 策略就是,一個 slot 只處理來自同一個 sequence 的請求;oldest 策略將會從 oldest requests 中形成一個 batch,但是這個 batch 不會包含多餘一個來自於同一個 sequence 的 request。對比一下就是,direct 每個 slot 的 請求都是來自同一個 sequence,oldest 每個 slot 的 請求來自不同的 sequence。
這裡讓我產生困惑的一點是 slot 和 batch 的關係。要明白一點,slot 構成 batch!
Direct 策略
一個 sequence 的請求都由一個 slot 處理。一個 sequence 會佔用一個 slot,如果所有的 slot 佔滿了,那麼就不會接下來的 sequence 會進入 backlog 進行等待。這個方法的缺點很明顯,就是 sequence 會佔用 slot,如果這個 sequence 一直不繼續請求,那麼這個 slot 就會浪費了。
Oldest 策略
同一個 batch 的請求,都來自不同的 sequence。