Rust實現大模型推理引擎:基於candle框架的輕量級實踐
為什麼用Rust做LLM推理?
Python是AI訓練的王者,但在推理部署上有致命短板:GIL鎖、記憶體開銷大、無零複製。
| 維度 | Python (PyTorch) | Rust (candle) |
|---|---|---|
| 執行時開銷 | 直譯器 + 框架,額外記憶體開銷大 | 無執行時,記憶體基本只有模型權重 |
| 冷啟動 | 通常 10-30 秒 | 約 2-5 秒(示例環境實測,僅供參考) |
| 記憶體安全 | 需手動管理 | 編譯期保證 |
| 並發模型 | GIL限制 | 無限制 |
candle框架
candle是HuggingFace開發的Rust ML框架:
- 純Rust實現,無Python依賴
- 支援CUDA和Metal GPU加速
- 零複製張量操作
- 支援GGML/GGUF量化格式
推理引擎核心
pub struct InferenceEngine {
model: Arc<RwLock<Model>>,
tokenizer: Tokenizer,
device: Device,
}
impl InferenceEngine {
pub async fn generate(&self, prompt: &str, max_tokens: usize) -> anyhow::Result<String> {
let tokens = self.tokenizer.encode(prompt, true)?;
let mut input_tokens = tokens.get_ids().to_vec();
let mut generated_tokens = Vec::new();
let model = self.model.read().await;
for _ in 0..max_tokens {
let input = Tensor::new(&input_tokens, &self.device)?.unsqueeze(0)?;
let logits = model.forward(&input, input_tokens.len() - 1)?;
let next_token = self.sample_token(&logits, &generated_tokens)?;
generated_tokens.push(next_token);
input_tokens.push(next_token);
}
let output = self.tokenizer.decode(&generated_tokens, true)?;
Ok(output)
}
}
誠實的效能定位
先給結論:本文實現的引擎定位於教學與輕量場景,不代表 candle 的吞吐上限,更不可能跑贏 vLLM。
上文引擎程式碼使用全域 RwLock 序列化前向計算、逐 token 前向、無批處理——物理上不可能達到數千 tok/s。網路上流傳的「candle 8,200 tok/s 碾壓 vLLM 2,500」之類數字沒有可信來源,本文早期版本也曾引用,現予刪除。
行業共識與獨立實測的結論恰好相反:
- 高並發吞吐:vLLM 憑藉 PagedAttention + 連續批處理(continuous batching)明顯更強;candle 類單請求實現的吞吐通常約為 vLLM 的 70% 左右(隨模型、硬體與量化格式波動,僅供參考)。
- candle 的真實優勢在部署形態:單二進位、無 Python 依賴、冷啟動快、執行時記憶體開銷低。
定性對比(部署維度)
| 維度 | vLLM | 本文 candle 引擎 |
|---|---|---|
| 高並發吞吐 | 強(PagedAttention + 連續批處理) | 弱(無批處理,逐請求序列) |
| 單請求延遲 | 低 | 低 |
| 部署依賴 | Python + CUDA 生態 | 單二進位,無 Python 依賴 |
| 冷啟動 | 通常 10-30 秒 | 約 2-5 秒(示例環境實測,僅供參考) |
| 執行時記憶體開銷 | Python 執行時 + 推理框架 | 基本只有模型權重 + KV cache |
| 適用場景 | 生產高並發服務 | 教學、邊緣/嵌入式、輕量服務 |
記憶體佔用的誠實數字
以 Qwen2.5-7B-Instruct Q4_0 為例:
- 權重:Q4_0 量化後約 4GB(每參數約 0.55 位元組,7B × 0.55 ≈ 3.9GB)
- KV cache:隨上下文長度與並發數增長,通常再增加 1-2GB
- 總計:約 5-6GB
任何「7B Q4_0 模型只佔 1.1GB 記憶體」的說法都違背基本算術——僅權重就約 4GB。本文早期版本中的該數字係錯誤,已修正。
總結
- 輕量部署:單二進位約 15MB(示例構建),無 Python 依賴,冷啟動約 2-5 秒(示例環境實測)
- 記憶體安全:無資料競爭、無空指標、無緩衝區溢位
- 低執行時開銷:記憶體基本只有模型權重 + KV cache,無直譯器與框架開銷
- 無GIL:真正的多執行緒併發
需要誠實指出:吞吐不是本方案的賣點。高並發生產場景請選擇 vLLM 等具備 PagedAttention 與連續批處理的推理引擎;candle 方案適合教學、邊緣部署和對部署形態敏感的輕量服務。
Rust不是要在吞吐上碾壓誰,而是給推理部署多一種形態——訓練用Python,高並發服務用vLLM,輕量/邊緣場景用Rust + candle。
#Rust#LLM推理#轻量部署#candle#推理引擎#内存安全