Jetson Nano:Ollama与最优量化
原文:https://dev.to/annavi11arrea1/jetson-nano-ollama-optimal-quantization-2de8
我很高兴地宣布,一位用户报告了功能异常,这让我得以深入探索并修复问题。在本地环境中调试是一回事,但为终端用户构建一个可用的应用时,使用"本地"AI 还需要考虑其他因素。这让我发现了硬件限制的有趣现象,并对量化及其重要性有了高层次的理解。我还解释了如何创造性地绕过这些限制。这个应用叫做 flippy card,它通过自定义上传内容帮助你学习。想看看吗?点这里:Flippycard
问题:
- Ollama 在本地循环中被 cloudflare 卡住。
- Ollama 需要通过配置文件在 systemctl 之外访问。
- Ollama 运行极其缓慢,需要设置为使用 GPU 而非 CPU。
- 必须从源码构建 Ollama 并指定使用 GPU。
实现方案:
- 确保 Ollama 通过 cloudflare 隧道传输。
- 创建配置文件使 Ollama 可从外部访问。
- 从源码构建以节省资源,Docker 对 Jetson Nano 来说资源消耗过大,难以保证性能。
- 通过从 CPU 切换到 GPU 来提升速度,这些设置需要明确指定。
- 密切关注系统资源,确保 Nano 不会面临崩溃风险。
我还在新的 techdocs 页面中添加了 Notes 部分,开始记录实现过程。
为了在 jetson orin nano 上节省资源,我从源码构建,耗时约 30 分钟。我担心将 8GB 内存推向极限,这确实是合理的担忧。我需要尽可能保持轻量化。尽管 Docker 容器很吸引人,但在预算有限的情况下选择并不多。
从源码构建步骤:
步骤 1:安装 CUD toolkit + cmake,命令如下:
Sudo apt install -y cuda-toolkit-13 cmake
步骤 2:安装 Go(arm 64):
Curl -LO https://go.dev/dl/go1.24.4.linix-arm64.tar.gx && sudo tar -C /usr/local -xzf go1.24.4.linux-arm64.tar.gz && rm go1.24.4.linux-arm64.tar.gz
步骤 3:将 Go 和 CUDA 添加到 PATH:
Echo 'export PATH=$PATH:/usr/local/bint:/usr/local/cuda-13/bin' >> ~/.bashrc && esport PATH=$PATH:/usr/local/go/bin:/usr/local/cuda-13/bin
步骤 4:使用 sm_87 克隆并构建 ollama:
Git clone https://github.com/ollama/ollama /home/anna/ollama-src && cd /hom/anna/ollama-src && CUDA_ARCHITECTURES=87 cmake
整个过程大约耗时 30 分钟。
效率
为了轻松分享这个过程,我将 gmail MCP 服务器连接到 claude,这样我就可以通过邮件将过程摘要发送给自己。
在 jetson nano 上最大化效率是个好选择。我真的不想在服务器上管理大量文档,所以我在新的 techdocs 页面上创建了一个专门记录技术探索的地方。我在 ollama 构建期间搭建了这个页面。考虑到资源限制,我要求 claude 在不会将小服务器资源推向极限的情况下,为我创建一个新页面来存放所有技术发现——我知道当前进程至关重要。它分析了情况,给出了真实反馈,并告诉我由于当前安装已经接近硬件能力极限,哪些操作是可行的。这是一个很好的启示,避免在重要进程运行时导致 PC 崩溃。由于一切已经运行,我只需几行代码就能轻松添加新路由。当然,我意识到我可以在另一台电脑上完成这些操作,但挑战硬件极限很有趣。
量化——新话题(对我来说)
量化:
"量化是降低数字信号精度的过程,通常从高精度格式转换为低精度格式。"(Brian Clark, IBM)
在最终让一切正常工作后,使用 Q8_0 版本的请求耗时 13 分 20 秒。这时我了解了量化。然后我尝试了另一个变体 Q4_0 来改善结果。
基准测试

以下是 Q8_0 与 Q4_K-M 量化的基准测试对比:
由于瓶颈是"模型无法完全放入 GPU 内存",我们测试了相同模型(llama3.2:1b)的更小量化版本,而不是切换到其他更弱的模型系列。
| 指标 | Q8_0(原始) | Q4_K_M |
|---|---|---|
| 模型文件大小 | 1.5 GB | 808 MB |
| GPU 层加载 | 3–9 of 17 | 17 of 17(100%) |
| 生成速度 | ~1.2–1.35 tok/s | ~30.7 tok/s |
| 实际 971 token 测试 | 13m 20s | ~35–45s |
这大约提升了 25 倍速度,因为整个模型现在完全运行在 GPU 上,而不是大部分依赖缓慢的 CPU 路径。太棒了!但代价是什么?
问题
Q4_K_M 速度快,但有时会产生格式错误的输出。
在切换之前,我使用 Q4_K_M 连续进行了 6 次测试生成以检查可靠性,因为低精度量化可能不太稳定。
结果如下:
- 2/6:完全有效的 JSON,结构正确
- 1/6:有效的 JSON,但使用了与预期略有不同的字段名
- 3/6:格式错误的 JSON(例如,括号不匹配),会直接导致应用解析器崩溃
这大约是每次尝试 50-65% 的失败率。即使速度大幅提升,我也不能明知故犯地发布这样的版本。
那么,如何处理 Q4 的错误行为呢?
与其放弃更快的模型,我在应用中添加了自动重试逻辑。如果模型的响应格式错误,应用现在会静默重试最多 3 次,然后才显示错误。由于每次 Q4_K_M 尝试只需约 30-45 秒,即使最坏情况下重试 3 次,仍然比单次保证缓慢的 Q8_0 请求快得多,同时将有效成功率提升到约 85-95%。
这优雅地处理了潜在的解析错误。由于 Q4 速度快了 25 倍,客户端几乎感觉不到延迟。
附注:我是在设置 Jetson 一个月后才发现它有"超级"功能的。别学我。先检查超级功能。它是免费下载的。XD