正在幫產品加一個『裝置端小助理』功能,老闆說要用既有的8美元ESP32控制板做,不准加錢換更貴的晶片
有工程師在一顆只要8美元的微控制器(microcontroller)比迷你電腦還簡化的晶片,通常只做特定簡單工作,例如控制家電或感測器,運算能力和記憶體都比手機、電腦小很多——ESP32-S3上,成功跑出一個2890萬參數(parameters)AI模型裡儲存『學到的東西』的數字,參數越多通常代表模型懂得越多,但也需要越多空間存放的語言模型。整個過程不連網,晶片自己一個字一個字把故事寫出來,顯示在旁邊接的小螢幕上,速度大約每秒9個字。
聽起來很基本,但難處在於這顆晶片的SRAM晶片內建、速度最快但容量很小的記憶體,像是隨手可拿的抽屜,存取快但放不下太多東西只有512KB。過去在類似等級的晶片上,人們只能塞進26萬參數的模型,因為傳統做法要求整個模型都要能被快速記憶體隨時讀到,模型稍微大一點,512KB的抽屜根本裝不下。
這次能塞進足足100倍大的模型,關鍵不是把模型『縮小』,而是先看清楚模型裡的資料其實不平等。語言模型有一大塊叫嵌入表(embedding table)AI模型裡把『字』轉換成一串數字的對照表,用來讓電腦讀懂文字的意義,它佔了模型裡大多數的參數,但工作方式只是『查』,不是『算』——生成每個字的時候只需要從表裡挑出幾行來看。既然是用查的,就不必隨時待在快速的SRAM裡,而是可以放進容量大但速度慢的Flash 快閃記憶體容量大但讀取速度較慢的儲存空間,像倉庫,東西放得下但要跑一趟去拿,需要的時候才去挖那幾行,一次大約只挖450位元組。真正需要隨時運算的『思考』核心,體積小很多,才留在SRAM裡。
這個把嵌入表挪去慢速儲存的招式,叫做Per-Layer Embeddings,原本是Google設計給Gemma系列模型用的,目標是讓模型能裝進手機。這次的特別之處,是把同樣的想法套用到比手機記憶體還小上千倍的微控制器上——作者說,據他所知,還沒有人在這麼小的晶片上試過。
| 項目 | 上一代(約26萬參數) | 這一代(2890萬參數) |
|---|---|---|
| 參數量 | 約26萬 | 約2,890萬(約100倍) |
| 主要瘦身招式 | 模型本身做得很小 | 嵌入表搬去Flash+4-bit量化 |
| 晶片SRAM需求 | 整包塞進SRAM | 僅運算核心留SRAM,約數十KB |
| 晶片成本 | 類似等級的微控制器 | 約8美元(ESP32-S3) |
| 生成速度 | 文章未提供對照數字 | 約9.5 tokens/秒 |
下面用一段簡化過的Python示範『隨用隨讀』的核心概念:嵌入表其實就是放在硬碟裡的一個大檔案,程式不會把整個檔案讀進記憶體,而是直接跳到需要的那一列,只挖那一小段出來。這不是原始韌體的真實程式碼(原版是C/C++,跑在ESP32上),但邏輯完全對應文章講的技巧。
ROW_BYTES = 75def get_embedding_row(file, token_id): file.seek(token_id * ROW_BYTES) return file.read(ROW_BYTES)with open("embedding_table.bin", "rb") as f: token_ids = [17, 902, 5] rows = [get_embedding_row(f, t) for t in token_ids]