Day 24 我已經確認,這個 Breakout 模型做一次決策其實只需要幾毫秒。
接下來我很好奇另一個很常見的最佳化方法:如果把 FP32 換成 FP16,會不會更快?
直覺上很合理。
FP32 用 32 個位元保存一個浮點數,FP16 只用 16 個位元。數字變小之後,模型檔案通常會縮小,GPU 要處理的資料也比較少,所以很多深度學習工作都會使用 FP16 來加速。
但真正值得問的其實有兩件事:
Day 25 就來實際測這兩件事。
這次 FP16 最明顯的優點,是模型真的變小很多:
FP32:13,175,034 bytes
FP16: 6,590,582 bytes
大約少了 49.98%。
但另外兩個結果就沒有那麼漂亮:
所以這不是一個「犧牲一點精度,換到很多速度」的故事。
比較像是:
檔案確實小了一半,但我沒有得到真正想要的速度收益。
下面這張圖就是這次實際測量的結果。
Breakout Agent 每次會替四個動作算出分數,也就是 Q-value。
可以先把它理解成:
模型估計現在做這個動作,之後大概能拿到多少回報。
最後 Agent 會選 Q-value 最高的動作。
問題在於,有時第一名和第二名非常接近。
例如:
RIGHT = 4.8123
LEFT = 4.8122
RIGHT 只高一點點。
如果換成 FP16 之後,因為能表示的數字沒有 FP32 那麼細,可能變成:
RIGHT = 4.812
LEFT = 4.812
甚至兩者順序稍微交換。
這時候最後選到的動作就可能不同。
我把同樣的 60 個遊戲狀態分別交給 FP32 和 FP16,得到:
| 執行方式 | 最大 Q-value 差異 | 最後動作一致率 |
|---|---|---|
| PyTorch:FP32 vs FP16 | 0.002798 | 93.33% |
| ONNX Runtime:FP32 vs FP16 | 0.002784 | 93.33% |
也就是說:
60 個固定狀態裡,有 4 個最後真的選到不同動作。
這是一個值得注意的訊號,但它不能單獨告訴我們 FP16 的整體遊戲能力一定比較差。
原因很簡單:強化學習不是只做一次分類,而是不斷和遊戲互動。
我也讓 FP32 和 FP16 從相同的遊戲起點開始玩。
只要前面某一步選到不同動作,後面就可能一路分開:
某一步選到不同動作
↓
球和板子的位置開始不同
↓
下一次看到的畫面也不同
↓
之後的決策繼續分岔
這是強化學習很典型的特性。
Agent 的動作會改變環境,而環境又會決定下一步看到什麼。
所以兩個版本只要在前面有一次選擇不同,後面就很難再逐步對照。
Day 25 的 15 局測試確實看到了這種現象:FP16 和 FP32 的遊戲路線很快分岔。
但這個結果比較適合解讀成:
FP16 的數值差異確實足以改變遊戲路線。
至於最後到底「比較會不會玩」,還是要看更多局的分數表現,而不是只看兩條路線有沒有完全一樣。
如果 FP16 真的能帶來明顯加速,那事情就值得繼續研究。
但 Day 25 的結果沒有走到這一步,因為 FP16 根本沒有速度優勢。
同一輪測試、一次處理一個遊戲狀態時:
| 執行方式 | FP32 P50 | FP16 P50 | FP32 P95 | FP16 P95 |
|---|---|---|---|---|
| PyTorch | 7.917 ms | 9.268 ms | 8.978 ms | 10.690 ms |
| ONNX Runtime | 4.140 ms | 5.342 ms | 5.541 ms | 6.727 ms |
P50 可以理解成一般情況下大概多快;P95 則是在看比較慢的那一小段情況。
這一輪裡:
也就是:
我承擔了額外的數值差異,卻沒有換到速度。
這才是 Day 25 最直接的不採用理由。
另外,Day 25 這組絕對毫秒數不拿來取代 Day 24 的正式速度基準。
兩天執行時的系統狀態不同,絕對延遲有明顯變化;Day 25 真正要看的,是同一輪測試裡 FP32 和 FP16 的相對差異。
而方向很清楚:FP16 沒有得到優勢。
因為「FP16 理論上計算量比較省」和「實際一次決策比較快」是兩件不同的事。
這個 Breakout 模型本身不大,而且一次只處理一個狀態。
真正的神經網路計算時間很短,這時候其他額外成本可能就變得很明顯,例如:
如果原本真正需要計算的工作就不多,FP16 理論上省下來的時間可能還不夠抵掉這些成本。
所以:
FP16 比較省,不代表每一種模型、每一種使用方式都一定比較快。
如果今天最大的問題是:
那模型小一半當然很有吸引力。
但這個 Breakout 模型原本只有大約 13 MB,檔案大小目前不是主要瓶頸。
相比之下,我更在意的是:
換成 FP16 之後,到底有沒有換到實際速度收益?
Day 25 的答案很清楚:沒有。
既然最期待的收益沒有出現,就沒有必要只為了把模型從 13 MB 壓到 6.6 MB,而額外接受更多數值差異。
FP16 當然不是沒用。
大型模型、一次處理很多資料,或某些特別適合半精度運算的硬體與工作負載,都可能從 FP16 得到很大的收益。
但這次實驗讓我看到一個更實際的事情:
最佳化不能只看理論,也不能只看模型檔案大小。
「位元變少」可以推出模型會變小,卻不能直接推出:
模型變小
= 一定更快
= 實際表現一定更好
Day 25 真正得到的是:
模型大小 → ✅ 小約 50%
固定狀態決策 → ⚠️ 60 個狀態有 4 個改變
遊戲路線 → ⚠️ 很快分岔
決策速度 → ❌ 沒有變快,反而更慢
所以最後仍然是:
這個模型目前不採用 FP16,繼續保留 FP32。
不是因為 FP16 一定會讓 Agent 變差,而是因為在這個 batch=1 的 Breakout 工作負載裡,它沒有帶來真正的速度收益。