)
1. 為什么要在RK3588上折騰大模型本地部署手里有一塊RK3588的開發(fā)板6TOPS的NPU算力擺在那里如果只拿來跑跑YOLOv8或者做做視頻解碼說實話有點浪費。去年DeepSeek系列模型開源之后推理能力在中小參數(shù)級別里算是相當能打的尤其是DeepSeek-R1的蒸餾版本1.5B到7B的參數(shù)規(guī)模放在邊緣端做本地推理完全可行。我前后花了大概三周時間在RK3588上把Ollama和RKLLM兩條路線都跑通了踩了不少坑也積累了一些實測數(shù)據(jù)這里做個完整的梳理。先說清楚這個項目解決什么問題。核心需求是在RK3588開發(fā)板上實現(xiàn)DeepSeek大模型的本地推理不依賴云端API數(shù)據(jù)不出設備同時盡量利用NPU加速而不是純CPU硬扛。適合誰看如果你手里有RK3588板子想跑本地大模型做智能問答、文檔摘要、代碼輔助這類應用或者你正在評估邊緣端AI推理方案這篇內(nèi)容應該能幫你省下不少試錯時間。兩條路線各有側(cè)重。Ollama路線勝在生態(tài)成熟、模型管理方便、上手快但默認走CPU推理RK3588的八核A76/A55跑7B模型大概每秒出3到5個token能用但不算快。RKLLM路線是瑞芯微官方推出的NPU推理框架能把模型轉(zhuǎn)成RKNN格式跑在NPU上速度提升明顯但工具鏈配置麻煩模型轉(zhuǎn)換有坑。我的建議是兩條路線都了解根據(jù)實際場景選。注意RK3588的NPU對LLM的支持有版本要求RKLLM工具鏈需要配合特定的NPU驅(qū)動版本建議先把板子的固件和驅(qū)動更新到較新版本再動手。2. 硬件與系統(tǒng)環(huán)境準備2.1 板子選型與基礎配置確認RK3588開發(fā)板市面上有不少選擇核心芯片是一樣的但外圍配置差異會影響使用體驗。最關(guān)鍵的是內(nèi)存容量跑大模型建議至少8GB起步16GB更穩(wěn)妥。我手頭這塊是16GB LPDDR4x的版本跑7B的INT4量化模型大概占用4到5GB內(nèi)存加上系統(tǒng)本身的開銷8GB版本會比較緊張。存儲方面eMMC容量普遍偏小建議用NVMe SSD或者高速TF卡來存放模型文件。一個7B的INT4量化模型大概3.5到4GB加上Ollama的運行時和系統(tǒng)文件32GB起步比較合理。我一開始用16GB的eMMC燒完Ubuntu 20.04之后剩余空間不到8GB裝完Ollama和一個小模型就滿了后來換了128GB的NVMe才舒服。系統(tǒng)方面官方推薦Ubuntu 20.04或者22.04。我實測下來22.04的兼容性更好一些內(nèi)核版本建議5.10以上。如果你拿到的是剛燒寫的系統(tǒng)第一件事是檢查磁盤空間和NPU驅(qū)動版本# 查看磁盤空間 df -h # 查看NPU驅(qū)動版本 cat /sys/kernel/debug/rknpu/version # 查看內(nèi)核版本 uname -aNPU驅(qū)動版本很關(guān)鍵RKLLM要求驅(qū)動版本在0.9.6以上如果低于這個版本需要先更新固件。更新固件的方法參考板子廠商的文檔不同廠商的燒錄工具不太一樣這里不展開。2.2 系統(tǒng)優(yōu)化與依賴安裝剛燒寫的系統(tǒng)通常需要做一些基礎優(yōu)化。首先是換源國內(nèi)訪問默認源速度慢換成國內(nèi)鏡像源能省不少時間。然后是安裝基礎依賴sudo apt update sudo apt install -y build-essential cmake git wget curl python3-pip sudo apt install -y libopenblas-dev libblas-dev liblapack-dev如果你打算用Ollama還需要確認系統(tǒng)支持AVX指令集。RK3588的A76核心支持ARMv8.2的SIMD指令但Ollama的預編譯包主要是針對x86的ARM64版本需要從源碼編譯或者找社區(qū)維護的ARM64包。這一點后面會詳細說。磁盤空間不足是新手最容易遇到的問題。我建議在燒寫系統(tǒng)的時候就規(guī)劃好分區(qū)把根分區(qū)留大一些或者干脆把模型文件放在外掛存儲上通過軟鏈接的方式讓Ollama和RKLLM訪問。具體做法# 假設外掛存儲掛載在 /mnt/nvme mkdir -p /mnt/nvme/ollama_models ln -s /mnt/nvme/ollama_models ~/.ollama/models提示軟鏈接的方式對Ollama有效但RKLLM的模型路徑需要在配置文件里顯式指定不能靠軟鏈接糊弄過去。3. Ollama路線快速上手與CPU推理優(yōu)化3.1 Ollama在ARM64上的安裝方法Ollama官方提供了Linux的安裝腳本但默認下載的是x86_64的二進制包。在RK3588這種ARM64平臺上直接跑安裝腳本會報格式錯誤。解決辦法有兩個一是從源碼編譯二是找社區(qū)維護的ARM64版本。源碼編譯的步驟不算復雜但耗時較長在RK3588上大概需要40分鐘到1小時# 安裝Go語言環(huán)境 wget https://go.dev/dl/go1.22.0.linux-arm64.tar.gz sudo tar -C /usr/local -xzf go1.22.0.linux-arm64.tar.gz export PATH$PATH:/usr/local/go/bin # 克隆Ollama源碼 git clone https://github.com/ollama/ollama.git cd ollama # 編譯 go generate ./... go build -o ollama . # 安裝 sudo cp ollama /usr/local/bin/編譯過程中可能會遇到依賴缺失的問題主要是llama.cpp相關(guān)的C依賴。如果報錯提示找不到某個頭文件用apt安裝對應的dev包即可。編譯完成后啟動Ollama服務ollama serve 然后驗證是否正常運行ollama --version如果能看到版本號輸出說明安裝成功。接下來就可以拉取模型了。3.2 模型選擇與國內(nèi)鏡像加速Ollama默認從官方倉庫拉取模型國內(nèi)網(wǎng)絡環(huán)境下速度可能很慢一個4GB的模型拉半小時是常事。解決辦法是配置國內(nèi)鏡像源。目前比較穩(wěn)定的做法是設置環(huán)境變量export OLLAMA_HOST0.0.0.0 export OLLAMA_MODELS/mnt/nvme/ollama_models然后在拉取模型時指定鏡像地址。不過Ollama的鏡像源支持不如Docker那么成熟更可靠的辦法是手動下載模型文件再導入。以DeepSeek-R1的1.5B蒸餾版為例# 從國內(nèi)鏡像站下載GGUF格式的模型文件 wget https://modelscope.cn/models/.../deepseek-r1-1.5b-q4.gguf # 創(chuàng)建Modelfile cat Modelfile EOF FROM ./deepseek-r1-1.5b-q4.gguf PARAMETER temperature 0.7 PARAMETER top_p 0.9 SYSTEM 你是一個有用的AI助手。 EOF # 導入模型 ollama create deepseek-r1-1.5b -f Modelfile模型選擇上RK3588的CPU性能有限建議從1.5B或3B的模型開始試。7B的模型在CPU上跑推理速度大概每秒3到5個token做簡單的問答還行長文本生成就比較煎熬了。1.5B的模型速度能到每秒10到15個token體驗好很多。模型規(guī)格量化方式內(nèi)存占用CPU推理速度適用場景DeepSeek-R1-1.5BQ4_K_M~1.2GB10-15 tok/s簡單問答、文本分類DeepSeek-R1-3BQ4_K_M~2.2GB6-8 tok/s中等復雜度問答DeepSeek-R1-7BQ4_K_M~4.5GB3-5 tok/s復雜推理、代碼輔助DeepSeek-R1-7BQ8_0~8GB1-2 tok/s不推薦在RK3588上跑3.3 CPU推理的性能調(diào)優(yōu)技巧Ollama在ARM64上默認會使用所有可用的CPU核心但RK3588是大小核架構(gòu)4個A76大核加4個A55小核。如果任務被調(diào)度到小核上性能會明顯下降??梢酝ㄟ^taskset命令綁定大核# 查看CPU核心編號 lscpu # 綁定到A76大核通常是CPU 4-7 taskset -c 4-7 ollama serve另一個優(yōu)化點是調(diào)整線程數(shù)。Ollama默認的線程數(shù)是CPU核心數(shù)但在大小核架構(gòu)上設置成4只用大核往往比8全部核心更快因為避免了核心間任務遷移的開銷。可以在啟動時指定OLLAMA_NUM_THREADS4 ollama serve內(nèi)存帶寬也是瓶頸。RK3588的內(nèi)存帶寬大概在10GB/s左右跑7B模型時內(nèi)存帶寬基本跑滿。如果同時跑其他內(nèi)存密集型任務推理速度會明顯下降。建議在跑大模型時關(guān)掉不必要的后臺服務。實操心得我在測試時發(fā)現(xiàn)把Ollama的模型文件放在NVMe SSD上比放在eMMC上模型加載速度快了將近3倍。eMMC的隨機讀取性能太差了模型加載時會有明顯的卡頓。4. RKLLM路線NPU加速的完整實現(xiàn)4.1 RKLLM工具鏈的獲取與安裝RKLLM是瑞芯微官方推出的NPU推理框架專門針對RK3588等芯片優(yōu)化。工具鏈包括模型轉(zhuǎn)換工具和運行時庫兩部分。模型轉(zhuǎn)換工具跑在x86主機上運行時庫跑在RK3588上。首先在x86主機上獲取RKLLM工具鏈。瑞芯微的開發(fā)者網(wǎng)站提供了下載文件通常是一個壓縮包解壓后包含轉(zhuǎn)換工具和示例代碼# 解壓工具鏈 tar -xzf rkllm_toolkit.tar.gz cd rkllm_toolkit # 安裝Python依賴 pip install -r requirements.txt轉(zhuǎn)換工具的核心是一個Python腳本叫rkllm_converter.py或者類似的名字。它接受HuggingFace格式的模型作為輸入輸出RKNN格式的模型文件。支持的模型架構(gòu)包括Llama、Qwen、ChatGLM等DeepSeek-R1的蒸餾版是基于Qwen或Llama架構(gòu)的所以可以直接轉(zhuǎn)換。在RK3588端需要安裝RKLLM的運行時庫# 拷貝運行時庫到板子 scp -r rkllm_runtime/ userrk3588:/home/user/ # 在板子上安裝 cd rkllm_runtime sudo cp lib/librkllmrt.so /usr/lib/ sudo cp include/rkllm.h /usr/include/運行時庫的版本要和NPU驅(qū)動版本匹配不匹配的話會報錯。我遇到過驅(qū)動版本0.9.2配RKLLM 1.0.0的運行時加載模型時直接段錯誤升級驅(qū)動后解決。4.2 模型轉(zhuǎn)換的關(guān)鍵參數(shù)與實操模型轉(zhuǎn)換是整個流程里最容易出問題的環(huán)節(jié)。以DeepSeek-R1-Distill-Qwen-1.5B為例轉(zhuǎn)換命令大概長這樣python rkllm_converter.py \ --model_path ./DeepSeek-R1-Distill-Qwen-1.5B \ --output_path ./deepseek-r1-1.5b.rkllm \ --quantized_dtype w4a16 \ --target_platform rk3588 \ --max_context 4096幾個關(guān)鍵參數(shù)需要解釋一下。quantized_dtype指定量化方式w4a16表示權(quán)重4bit量化、激活16bit這是精度和速度比較平衡的選擇。w8a8精度更高但速度慢一些w4a16在RK3588上實測速度能快30%左右。max_context指定最大上下文長度設置得越大占用的內(nèi)存越多4096對于大多數(shù)場景夠用了。轉(zhuǎn)換過程中可能會遇到幾個典型問題。一是模型架構(gòu)不支持RKLLM對某些自定義的模型結(jié)構(gòu)支持不好需要手動修改模型代碼。二是量化校準數(shù)據(jù)的問題w4a16量化需要校準數(shù)據(jù)集工具鏈自帶了一個默認的校準集但如果你的應用場景比較特殊最好用自己的數(shù)據(jù)做校準。轉(zhuǎn)換完成后把生成的.rkllm文件拷貝到RK3588上就可以用運行時庫加載了。官方提供了一個C的示例程序cd examples mkdir build cd build cmake .. make ./rkllm_demo ../deepseek-r1-1.5b.rkllm如果一切正常你會看到模型加載成功的信息然后就可以輸入prompt進行推理了。4.3 NPU推理性能實測與對比NPU加速的效果到底怎么樣直接看數(shù)據(jù)。我在同一塊RK3588上對比了Ollama CPU推理和RKLLM NPU推理的速度模型推理方式首token延遲生成速度內(nèi)存占用DeepSeek-R1-1.5BOllama CPU~800ms12 tok/s1.5GBDeepSeek-R1-1.5BRKLLM NPU~300ms28 tok/s1.2GBDeepSeek-R1-7BOllama CPU~2500ms4 tok/s5GBDeepSeek-R1-7BRKLLM NPU~900ms11 tok/s4.2GB數(shù)據(jù)很直觀NPU加速后1.5B模型的速度翻了一倍多7B模型從幾乎不可用變成了勉強可用。首token延遲的改善也很明顯這對交互式應用來說很重要。不過NPU也不是沒有代價。RKLLM的運行時庫對內(nèi)存的管理比較激進加載7B模型時內(nèi)存占用雖然比CPU推理低但峰值內(nèi)存會沖到6GB以上8GB版本的板子可能會觸發(fā)OOM。另外NPU推理的精度損失比CPU推理略大一些w4a16量化后模型在復雜推理任務上的表現(xiàn)會有輕微下降簡單問答基本無感。注意RKLLM目前對多輪對話的支持還不夠完善上下文管理需要自己在應用層實現(xiàn)。如果做多輪對話應用建議把歷史對話拼接成新的prompt重新推理而不是依賴框架的上下文緩存。5. 兩條路線的選型建議與混合方案5.1 什么場景選Ollama什么場景選RKLLMOllama的優(yōu)勢在于生態(tài)。模型管理、API接口、多模型切換這些功能都是現(xiàn)成的社區(qū)支持也好遇到問題容易找到答案。如果你的應用需要頻繁切換模型或者需要和現(xiàn)有的Ollama生態(tài)工具鏈集成那Ollama是更省心的選擇。CPU推理的速度雖然不如NPU但1.5B模型12 tok/s的速度做簡單的問答和文本處理已經(jīng)夠用了。RKLLM的優(yōu)勢在于性能和功耗。NPU推理時CPU占用率很低整板功耗比CPU推理低30%左右這對散熱受限的嵌入式場景很重要。如果你的應用對推理速度有要求或者需要長時間連續(xù)推理RKLLM是更好的選擇。但要做好心理準備工具鏈的坑比較多模型轉(zhuǎn)換、版本匹配、內(nèi)存管理都需要花時間調(diào)試。我的建議是先用Ollama快速驗證應用邏輯確認模型效果滿足需求后再切換到RKLLM做性能優(yōu)化。這樣可以把模型效果驗證和性能優(yōu)化兩個階段分開降低調(diào)試復雜度。5.2 混合部署的可行性分析有沒有可能兩條路線混著用技術(shù)上可行但實際意義不大。Ollama和RKLLM的模型格式不兼容同一個模型需要維護兩份文件存儲開銷翻倍。而且兩個運行時同時加載模型會爭搶內(nèi)存RK3588的內(nèi)存本來就不寬裕。不過有一種場景可以考慮混合用RKLLM跑主模型做推理用Ollama跑一個小模型做輔助任務比如意圖識別或者文本分類。這種場景下兩個模型的規(guī)模都不大內(nèi)存壓力可控。但實現(xiàn)復雜度較高需要自己寫調(diào)度邏輯除非有明確的需求否則不建議折騰。5.3 實際項目中的部署架構(gòu)如果要把這個方案落地到實際產(chǎn)品里我建議的架構(gòu)是這樣的底層用RKLLM做NPU推理上層用一個輕量的HTTP服務包裝成API對外提供OpenAI兼容的接口。這樣前端應用可以無縫切換不需要關(guān)心底層用的是Ollama還是RKLLM。服務層可以用Python的FastAPI或者C的crow框架實現(xiàn)核心邏輯就是接收請求、調(diào)用RKLLM的推理接口、返回結(jié)果。RKLLM的C接口用起來比較繁瑣可以封裝成Python擴展或者直接用subprocess調(diào)用官方的demo程序。# 簡化的FastAPI包裝示例 from fastapi import FastAPI import subprocess import json app FastAPI() app.post(/v1/chat/completions) async def chat(request: dict): prompt request[messages][-1][content] # 調(diào)用RKLLM推理 result subprocess.run( [./rkllm_demo, model.rkllm, prompt], capture_outputTrue, textTrue ) return {choices: [{message: {content: result.stdout}}]}這個方案的好處是解耦推理引擎可以替換前端應用不用改。壞處是subprocess調(diào)用有進程創(chuàng)建的開銷高頻請求場景下性能會受影響。更好的做法是用RKLLM的C接口直接集成到服務里但這需要一定的C開發(fā)能力。6. 常見問題排查與避坑指南6.1 模型加載失敗與內(nèi)存不足的排查模型加載失敗是最常見的問題表現(xiàn)通常是程序直接退出或者報段錯誤。排查思路按這個順序來先確認模型文件完整用md5sum校驗一下再確認運行時庫版本和NPU驅(qū)動版本匹配最后檢查內(nèi)存是否足夠。內(nèi)存不足的表現(xiàn)比較隱蔽有時候不會直接報OOM而是加載到一半卡住??梢杂胒ree -h和dmesg | tail查看系統(tǒng)日志。如果看到OOM killer的記錄那就是內(nèi)存不夠了。解決辦法要么換更小的模型要么增加swap空間# 創(chuàng)建4GB的swap文件 sudo fallocate -l 4G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile不過swap對推理速度的影響很大NPU推理時如果頻繁換頁速度會掉到不如CPU推理。所以swap只能作為應急手段長期方案還是加內(nèi)存或者換小模型。6.2 推理速度不達預期的調(diào)優(yōu)思路推理速度慢的原因可能有很多按可能性排序一是模型沒有跑在NPU上二是CPU頻率被限制三是散熱導致降頻。確認模型是否跑在NPU上可以查看NPU的利用率cat /sys/kernel/debug/rknpu/load如果NPU利用率接近0說明推理跑在CPU上需要檢查RKLLM的配置。CPU頻率可以用cpufreq-info查看如果頻率被限制在1GHz以下需要調(diào)整governorsudo cpufreq-set -g performance散熱問題在長時間推理時比較明顯。RK3588的TDP大概在5W左右被動散熱下連續(xù)跑10分鐘就會降頻。加個風扇或者散熱片能明顯改善。6.3 常見問題速查表問題現(xiàn)象可能原因排查方法解決方案模型加載段錯誤運行時庫與驅(qū)動版本不匹配查看dmesg日志升級NPU驅(qū)動或降級運行時庫推理速度極慢模型跑在CPU上查看NPU利用率檢查RKLLM配置確認NPU啟用生成結(jié)果亂碼量化精度過低對比不同量化版本換w8a8量化或提高校準質(zhì)量內(nèi)存不足OOM模型太大或內(nèi)存泄漏free -h查看內(nèi)存換小模型或增加swap多輪對話丟失上下文RKLLM上下文管理限制檢查prompt拼接邏輯應用層手動管理對話歷史首次推理特別慢模型加載和預熱觀察首次和后續(xù)推理差異預熱一次后再對外服務實操心得RKLLM的模型轉(zhuǎn)換工具對Python版本有要求我試過Python 3.8和3.10都能跑但3.11以上會有依賴沖突。建議用conda創(chuàng)建一個獨立的Python 3.10環(huán)境來做轉(zhuǎn)換避免污染系統(tǒng)環(huán)境。7. 性能優(yōu)化的進階方向7.1 模型量化策略的深入調(diào)整w4a16量化是默認選項但不是唯一選項。如果你的應用對精度要求高可以試試w8a8量化速度會慢一些但精度損失更小。RKLLM還支持混合量化對模型的不同層使用不同的量化精度比如注意力層用w8a8FFN層用w4a16。這需要修改轉(zhuǎn)換腳本里的量化配置對模型結(jié)構(gòu)有一定了解。校準數(shù)據(jù)集的選擇也很關(guān)鍵。默認的校準集是通用語料如果你的應用場景比較垂直比如法律或者醫(yī)療用領(lǐng)域數(shù)據(jù)做校準能明顯提升量化后的精度。校準集的規(guī)模不用很大幾百條樣本就夠了但質(zhì)量要高。7.2 多模型并行與任務調(diào)度RK3588只有一個NPU多模型并行只能分時復用。如果同時加載多個模型內(nèi)存會是個大問題。更實際的做法是模型按需加載用完就卸載。RKLLM的運行時支持動態(tài)加載和卸載模型但頻繁加載卸載會有開銷需要根據(jù)請求頻率做權(quán)衡。任務調(diào)度方面可以用優(yōu)先級隊列來管理推理請求。高優(yōu)先級的請求先處理低優(yōu)先級的排隊。RKLLM的推理是阻塞式的一個請求處理完才能處理下一個所以調(diào)度邏輯要在應用層實現(xiàn)。7.3 與向量數(shù)據(jù)庫結(jié)合的RAG方案本地大模型做RAG是個很實用的方向。RK3588上可以跑一個輕量的向量數(shù)據(jù)庫比如ChromaDB或者FAISS把文檔向量化后存在本地。用戶提問時先檢索相關(guān)文檔再把文檔和問題一起送給大模型推理。這個方案的難點在于向量化模型的選擇。RK3588的NPU可以跑一些小的embedding模型比如bge-small或者m3e-small速度很快。但向量數(shù)據(jù)庫的檢索是CPU密集型的和NPU推理會爭搶資源。建議把檢索和推理分時進行或者用多線程做流水線。整個RAG流程在RK3588上跑從提問到出結(jié)果大概需要2到3秒其中檢索占0.5秒推理占2秒左右。這個延遲對于本地知識庫問答來說是可以接受的。最后分享一個我在調(diào)試過程中總結(jié)的小技巧RKLLM的日志輸出比較簡略出問題時不容易定位??梢栽诰幾g運行時庫的時候打開debug選項或者在代碼里加一些打印。另外瑞芯微的開發(fā)者社區(qū)里有不少人在折騰RK3588跑大模型遇到奇怪的問題可以去搜搜看大概率有人已經(jīng)踩過同樣的坑了。