资讯详情

资讯详情

建站行业动态 · 设计趋势 · 数字化升级干货

Jetson Nano部署DeepSeek大模型:ARM边缘计算实战指南

Jetson Nano部署DeepSeek大模型:ARM边缘计算实战指南 1. 项目概述为什么要在Jetson Nano上折腾DeepSeek最近手头有个闲置的Jetson Nano开发板看着它4GB的内存和相对羸弱的CPU总觉得让它跑跑简单的视觉Demo有点大材小用或者说没把它的潜力榨干。正好DeepSeek这类开源大模型火得不行我就琢磨着能不能把这“老伙计”变成一个本地的、能跑起来的AI对话终端毕竟云端API调用有延迟、有费用还涉及隐私如果能在本地设备上跑通一个可用的模型哪怕能力弱一些对于学习、调试或者一些简单的离线任务意义还是很大的。这个项目的核心目标就是在基于ARM架构的NVIDIA Jetson Nano开发板上成功部署并运行DeepSeek大语言模型。这里说的“运行”不是指调用云端API而是指通过Ollama这类工具将模型文件拉取到本地并在Jetson Nano的硬件上完成推理。整个过程会涉及到ARM64环境的适配、CUDA的配置、Ollama的安装与模型拉取以及最后在终端或通过API进行测试。对于拥有类似边缘计算设备如树莓派、其他Jetson系列的开发者来说这是一次非常典型的“边缘AI”实践能让你深刻理解从云端模型到边缘部署的全链路挑战和解决方案。2. 环境准备与深度解析Jetson Nano的“底子”与挑战在开始动手之前我们必须对Jetson Nano的硬件和系统环境有一个清醒的认识。这不是一台x86的PC它的每一步操作都可能遇到ARM架构带来的“惊喜”。2.1 硬件与系统基础盘点我使用的是一台Jetson Nano 4GB开发者套件版。它的核心配置如下CPU: 四核ARM Cortex-A57 1.43 GHz。这个性能大概相当于几年前的中端手机处理器处理复杂编译任务时会比较慢。GPU: 128核NVIDIA Maxwell架构GPU。这是我们的主力所有AI推理计算都指望它了。虽然架构老但支持CUDA这就是价值所在。内存: 4GB LPDDR4。这是最大的瓶颈大模型动辄需要数GB甚至数十GB的内存4GB意味着我们只能运行参数量较小的模型版本通常是7B参数以下的量化版。存储: 我为其配备了一张64GB的microSD卡。系统、软件、模型都放在这里。读写速度会直接影响体验建议使用Class 10或UHS-I以上规格的卡。系统方面我刷写了NVIDIA官方提供的JetPack 4.6.1镜像具体版本号可能随时间更新请以官网最新为准。这个镜像包含了Ubuntu 18.04 LTS、CUDA 10.2、cuDNN 8.x等一整套为Jetson优化的软件栈。非常重要的一点请务必使用NVIDIA官方提供的镜像而不是自己安装Ubuntu再配驱动那会是一场灾难。官方镜像已经做好了内核、驱动、CUDA的深度集成。开机后第一件事是检查基础环境# 查看系统版本和内核 cat /etc/os-release uname -a # 查看CUDA和GPU信息 nvcc --version # 如果提示命令未找到可能需要将/usr/local/cuda/bin加入PATH nvidia-sminvidia-smi这个命令很关键它能告诉你GPU是否被正确识别、驱动是否加载、以及当前GPU的内存使用情况。在Jetson Nano上它的输出可能不像服务器显卡那样信息丰富但只要能显示GPU型号和少量内存信息就说明基础环境是OK的。2.2 依赖安装与系统优化Jetson Nano的默认镜像为了节省空间很多开发工具没有预装。我们需要先补全一些基础依赖。# 更新软件源并升级现有包 sudo apt-get update sudo apt-get upgrade -y # 安装编译、下载等基础工具 sudo apt-get install -y \ curl \ wget \ git \ build-essential \ libssl-dev \ zlib1g-dev \ libbz2-dev \ libreadline-dev \ libsqlite3-dev \ llvm \ libncurses5-dev \ libncursesw5-dev \ xz-utils \ tk-dev \ libffi-dev \ liblzma-dev \ python3-openssl接下来是Python环境。系统自带了Python 3.6但有些新工具可能要求更高版本。我选择使用pyenv来管理多版本Python这样更灵活也不会破坏系统自带的Python。# 安装pyenv curl https://pyenv.run | bash # 将pyenv初始化脚本添加到shell配置文件中如 ~/.bashrc echo export PATH$HOME/.pyenv/bin:$PATH ~/.bashrc echo eval $(pyenv init -) ~/.bashrc echo eval $(pyenv virtualenv-init -) ~/.bashrc source ~/.bashrc # 安装一个较新的Python版本例如Python 3.10.13 # 注意在Jetson Nano上编译Python非常耗时可能需要1-2小时 pyenv install 3.10.13 # 设置为全局默认版本 pyenv global 3.10.13 # 验证 python --version pip --version注意在ARM设备上从源码编译Python是一个极其漫长的过程期间CPU会满载开发板可能会比较热。请确保供电充足最好使用桶形电源而非Micro USB供电并耐心等待。如果中途失败多半是内存不足可以尝试增加swap空间。系统优化项交换空间Swap4GB内存跑大模型很容易爆掉。增加Swap空间相当于用存储空间模拟内存能防止进程因内存不足OOM被系统杀死。但SD卡速度慢Swap用多了会卡顿这是权衡。# 创建一个8GB的交换文件 sudo fallocate -l 8G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile # 为了开机自动挂载将下面一行添加到 /etc/fstab # /swapfile none swap sw 0 0电源模式Jetson Nano有两种电源模式5W和10WMax-N。10W模式能解锁CPU和GPU的更高频率性能更好但需要足够的散热。如果你使用了风扇散热片建议设置为10W模式。sudo nvpmodel -m 0 # 0代表10W模式Max-N1代表5W模式 sudo jetson_clocks # 启用风扇并设置静态时钟性能模式3. Ollama的安装与配置在ARM64上的特别之旅Ollama是目前在本地运行大模型非常流行的工具它简化了模型下载、加载和提供API的整个过程。但官方安装脚本主要针对x86_64架构我们需要为ARM64特别是Jetson的aarch64进行手动安装。3.1 手动安装OllamaOllama本身是一个Go语言编写的二进制文件我们需要下载适用于ARM64的版本。# 前往Ollama的GitHub发布页找到最新的Linux ARM64版本下载链接 # 例如链接可能过期请检查最新版本 curl -L -o ollama-linux-arm64 https://github.com/ollama/ollama/releases/download/v0.1.40/ollama-linux-arm64 # 赋予执行权限并移动到系统路径 chmod x ollama-linux-arm64 sudo mv ollama-linux-arm64 /usr/local/bin/ollama # 验证安装 ollama --version如果/usr/local/bin不在你的PATH中可以将其加入或者直接使用绝对路径/usr/local/bin/ollama。3.2 配置Ollama服务与国内镜像为了让Ollama在后台持续运行并提供服务我们将其设置为系统服务。# 创建Ollama服务用户可选但推荐 sudo useradd -r -s /bin/false -m -d /usr/share/ollama ollama # 创建服务文件 sudo tee /etc/systemd/system/ollama.service EOF [Unit] DescriptionOllama Service Afternetwork-online.target [Service] Typeexec Userollama Groupollama ExecStart/usr/local/bin/ollama serve Restartalways RestartSec3 EnvironmentPATH/usr/local/bin:/usr/bin:/bin EnvironmentOLLAMA_HOST0.0.0.0 # 允许非本地连接方便其他设备访问 EnvironmentOLLAMA_ORIGINS* # 允许所有来源的CORS请求开发环境生产需限制 # 可选如果你配置了国内镜像源可以在这里设置 # EnvironmentOLLAMA_MODELS/path/to/your/local/models # 自定义模型存储路径 [Install] WantedBydefault.target EOF # 重新加载systemd配置 sudo systemctl daemon-reload # 启用服务开机自启 sudo systemctl enable ollama # 启动服务 sudo systemctl start ollama # 查看服务状态 sudo systemctl status ollama如果状态显示为active (running)说明服务启动成功。默认情况下Ollama的API服务会运行在11434端口。关于模型下载直接从Ollama官方拉取模型对于国内用户可能非常慢甚至不可行。这里有两个解决方案使用国内镜像源推荐一些社区维护了Ollama模型的镜像。你可以在运行ollama pull命令前通过环境变量或修改配置来指定镜像站。例如镜像站地址需自行寻找可用的export OLLAMA_MODEL_SOURCEhttps://mirror.example.com/ollama ollama pull deepseek-coder:6.7b请注意镜像站的可用性和完整性需要自行甄别。手动导入模型文件先从其他网络环境好的机器下载模型文件通常是Modelfile和多个二进制分片然后传输到Jetson Nano上使用ollama create和ollama run来手动创建模型。具体步骤可以参考Ollama官方文档关于“从GGUF文件创建”的部分。这需要你对模型文件格式有一定了解。实操心得在Jetson Nano上我强烈建议先在其他电脑比如x86的笔记本上用Ollama把需要的模型pull下来。模型文件通常存储在~/.ollama/models目录下。然后将这个目录整个打包通过SCP或者U盘拷贝到Jetson Nano的对应位置注意用户权限如果是ollama用户运行服务则需要将文件放在/usr/share/ollama/.ollama/models或类似路径并修改所有者。这能节省大量时间和避免网络问题。4. 拉取与运行DeepSeek模型选择与适配的博弈Ollama支持很多模型但并非所有模型都适合Jetson Nano。我们需要考虑两个关键约束内存和架构。4.1 模型选择量化版本是唯一出路原始的DeepSeek Coder 6.7B或DeepSeek-V2等模型仅FP16精度就需要超过13GB的GPU内存这远远超出了Jetson Nano的4GB物理内存8GB Swap的能力。因此我们必须使用量化模型。量化是一种模型压缩技术通过降低模型权重参数的数值精度例如从FP16降到INT4、INT8来大幅减少模型大小和内存占用同时尽可能保持模型性能。常见的量化格式有GGUFllama.cpp社区推动、GPTQ、AWQ等。Ollama主要支持GGUF格式。对于Jetson Nano 4GB我的经验是7B参数模型可以尝试q4_0或q4_K_M等4位量化版本。加载后GPU内存占用大约在3-4GB会非常紧张推理速度慢且极易触发Swap导致卡顿。更小的模型如1B-3B是更实际的选择。例如deepseek-coder:1.3b、phi系列、tinyllama等。它们能在有限内存下提供更流畅的交互体验。假设我们决定尝试deepseek-coder:6.7b的量化版。首先需要查看Ollama支持的该模型的标签tag。# 搜索deepseek相关模型需要网络 ollama list | grep deepseek # 或者去Ollama官网查看模型库https://ollama.com/library # 假设我们找到了一个合适的标签例如 deepseek-coder:6.7b-q4_0 # 拉取模型这将开始下载耗时很长 ollama pull deepseek-coder:6.7b-q4_0重要提示在Jetson Nano上直接执行ollama pull很可能因为网络或内存问题失败。如前所述强烈建议在其它机器上拉取后拷贝过来。4.2 手动处理模型文件备用方案如果Ollama官方库没有你想要的特定量化版本或者你想使用自己转换的GGUF模型可以手动操作。获取GGUF模型文件从Hugging Face等社区平台下载对应模型的GGUF格式文件例如deepseek-coder-6.7b-instruct.Q4_K_M.gguf。创建Modelfile这是一个告诉Ollama如何加载模型的配置文件。# Modelfile 示例 FROM /绝对/路径/到/你的/deepseek-coder-6.7b-instruct.Q4_K_M.gguf # 设置一些参数 PARAMETER temperature 0.7 PARAMETER top_p 0.9 PARAMETER num_ctx 2048 # 上下文长度根据模型能力和内存调整越小越省内存将上述内容保存为Modelfile文件。创建并运行模型# 在Modelfile所在目录执行 ollama create my-deepseek -f ./Modelfile # 运行模型 ollama run my-deepseek4.3 首次运行与性能观察当你第一次执行ollama run时Ollama会加载模型到内存。这是最紧张的时刻。# 在终端中交互式运行 ollama run deepseek-coder:6.7b-q4_0 # 或者运行你自定义的模型 # ollama run my-deepseek观察终端输出。你会看到加载进度条。同时打开另一个终端运行以下命令监控系统资源# 监控GPU使用情况 watch -n 1 nvidia-smi # 监控内存和Swap使用情况 watch -n 1 free -h # 监控整体系统负载 htop如果模型成功加载并出现了提示符例如恭喜你最艰难的一步已经完成你可以尝试输入一些简单的编程问题或对话。性能预期管理在Jetson Nano上运行6.7B的4位量化模型生成速度可能只有1-3个token/秒。对于简单的代码补全或问答尚可接受但进行长文本对话会非常需要耐心。更小的模型如1.3B速度会快很多可能达到10-20 token/秒。5. 高级配置与优化榨干每一分性能基础运行只是第一步要让体验更好还需要一些优化。5.1 调整Ollama运行参数通过环境变量或在ollama run时传递参数可以调整模型运行方式以更好地适应Jetson Nano。限制运行线程默认Ollama可能会使用所有CPU核心在ARM上有时反而会因调度开销降低效率。可以尝试限制使用的CPU核心数。# 通过numa控制但Jetson Nano是单节点更简单的方法是使用taskset # 首先找到ollama serve进程的PID ps aux | grep ollama # 然后用taskset绑定到特定CPU核心例如核心0和1 sudo taskset -cp 0,1 PID更一劳永逸的方法是在systemd服务文件[Service]部分添加EnvironmentOMP_NUM_THREADS2 # 限制OpenMP线程数 TasksMax50% # 限制CPU使用率systemd特性调整模型加载参数在Modelfile或运行命令中可以调整关键参数来平衡速度和内存。ollama run deepseek-coder:6.7b-q4_0 --num_ctx 1024 --num_batch 256 --num_gpu_layers 20--num_ctx 1024将上下文长度从默认的2048减半显著减少内存占用。--num_batch 256处理提示时的批次大小影响内存和速度。--num_gpu_layers 20指定将模型的前20层放在GPU上运行其余在CPU。这个数字需要反复试验放太多GPU内存不够放太少GPU加速效果差。对于6.7B模型在4GB Jetson上10-30层是一个可以尝试的范围。5.2 使用API接口与外部工具集成Ollama默认在http://127.0.0.1:11434提供与OpenAI兼容的API。这意味着你可以用任何支持OpenAI API的客户端来连接它。使用curl测试APIcurl http://127.0.0.1:11434/api/generate -d { model: deepseek-coder:6.7b-q4_0, prompt: 用Python写一个快速排序函数, stream: false }配置VS Code或Cursor等编辑器许多现代代码编辑器支持配置本地大模型作为补全或聊天助手。在VS Code中安装Continue或CodeGPT等插件。在插件设置中将API Base URL设置为http://localhost:11434/v1注意/v1后缀。API Key可以留空或随意填写。模型名称填写你在Ollama中拉取的模型名如deepseek-coder:6.7b-q4_0。这样你就可以在熟悉的编辑器环境中获得由本地Jetson Nano提供的代码补全和建议了虽然速度不快但隐私性极佳。5.3 编写自动化脚本与管理多个模型当你有多个模型或需要定期执行某些任务时脚本非常有用。一个简单的对话脚本(chat_with_deepseek.py)import requests import json def ask_ollama(prompt, modeldeepseek-coder:6.7b-q4_0, hostlocalhost, port11434): url fhttp://{host}:{port}/api/generate payload { model: model, prompt: prompt, stream: False, options: { num_ctx: 1024, temperature: 0.7 } } try: response requests.post(url, jsonpayload, timeout300) # 设置长超时 response.raise_for_status() return response.json()[response] except requests.exceptions.RequestException as e: return fError: {e} if __name__ __main__: while True: user_input input(\nYou: ) if user_input.lower() in [exit, quit]: break print(\nDeepSeek: , end, flushTrue) answer ask_ollama(user_input) print(answer)模型管理脚本用于切换不同任务所需的模型。#!/bin/bash # switch_model.sh MODEL_NAME$1 # 停止当前可能运行的ollama服务粗暴但有效 sudo systemctl stop ollama # 等待进程完全结束 sleep 3 # 这里可以做一些清理工作比如清空GPU内存如果有其他进程占用 # 实际上ollama停止后GPU内存会被释放 # 启动服务并运行指定模型 sudo systemctl start ollama sleep 5 # 等待服务启动 ollama run $MODEL_NAME6. 常见问题与排查实录我踩过的那些坑在这一路上我遇到了不少问题这里把典型的几个和解决方法记录下来希望能帮你节省时间。6.1 内存不足OOM问题症状运行ollama run时进程被杀死终端显示Killed或者系统变得极其卡顿然后Ollama服务崩溃。dmesg日志中能看到Out of memory相关记录。排查与解决确认模型大小首先确保你拉的模型是量化版q4, q5, q8等并且参数规模如6.7B对于4GB内存来说已经是极限。优先尝试更小的模型如1.3B, 3B。增加Swap空间如前所述将Swap扩大到8GB甚至16GB如果SD卡空间足够。这不能提升速度但能防止进程被直接杀死。调整模型参数这是最有效的手段。在运行或创建模型时强制减少上下文长度num_ctx例如从4096降到1024或512。这能线性减少内存占用。卸载无用进程关闭图形界面如果不需要进入纯命令行模式可以节省不少内存。使用sudo systemctl set-default multi-user.target然后重启。监控工具养成使用htop和nvidia-smi的习惯在运行模型前先看看空闲内存有多少。6.2 模型加载失败或输出乱码症状模型能拉取但运行时报错例如unexpected tensor type或者生成的内容全是乱码、重复字符。排查与解决模型文件损坏这是最常见的原因尤其是在网络不好时拉取的模型。解决方法是用ollama rm model-name删除模型然后重新拉取建议在稳定网络环境下进行。或者使用ollama pull的--insecure参数跳过某些校验不推荐。量化格式不兼容Ollama的GGUF加载器可能对某些非常新的或特殊的量化格式支持不好。尝试换一个更通用的量化类型例如从q4_K_M换成q4_0。Modelfile配置错误如果你是自己创建Modelfile检查FROM指令指向的GGUF文件路径是否正确文件是否有读取权限。6.3 Ollama服务无法启动或端口占用症状执行sudo systemctl status ollama显示失败或者用curl测试API连接超时。排查与解决检查端口占用11434端口可能被其他程序占用。使用sudo netstat -tlnp | grep 11434查看。检查服务日志使用sudo journalctl -u ollama -f实时查看服务日志里面通常有具体的错误信息。权限问题如果修改了模型存储路径或者用不同用户运行过Ollama可能导致权限混乱。检查/usr/share/ollama目录及其子目录的所有者和权限确保运行Ollama服务的用户如ollama有读写权限。二进制文件兼容性确保下载的Ollama二进制文件是ARM64版本而不是x86_64版本。可以用file /usr/local/bin/ollama命令检查。6.4 推理速度极慢症状模型能运行但生成每个词都要等好几秒甚至十几秒。排查与解决检查是否在用GPU这是最关键的一点。运行模型时观察nvidia-smi看GPU利用率Volatile GPU-Util是否在波动。如果一直是0%说明模型完全运行在CPU上速度必然极慢。这通常是因为num_gpu_layers参数设置为0或者模型不支持GPU卸载。确保在运行命令或Modelfile中设置了合适的num_gpu_layers一个大于0的值。Swap频繁使用如果free -h显示Swap使用量used很高且si/soswap in/out数值持续不为0说明内存严重不足系统在频繁使用低速的Swap导致整体卡顿。此时只能换更小的模型或进一步降低num_ctx。电源和散热确认Jetson Nano运行在10W模式sudo nvpmodel -m 0并且散热良好。过热会导致CPU/GPU降频性能下降。可以加装风扇或散热片。使用更高效的量化在模型精度可接受的范围内使用更激进的量化。例如从q8_0换到q4_0模型体积和计算量都会减小。6.5 网络问题与镜像源配置症状ollama pull速度极慢或者根本连不上。排查与解决使用国内镜像这是最有效的解决方案。积极搜索可用的Ollama国内镜像站并通过环境变量配置。手动下载再导入如前面反复强调的在PC端下载好模型文件GGUF然后通过SCP、U盘等方式拷贝到Jetson Nano。在Jetson上使用ollama create从本地文件创建模型。这是绕过网络问题最彻底的方法。代理配置需合规如果你有合规的网络访问方式可以在系统或Ollama服务级别配置。但请注意配置代理本身需要谨慎处理确保符合所有相关规定。整个项目折腾下来最大的体会就是“妥协的艺术”。在Jetson Nano这样的资源受限边缘设备上部署大模型你必须在模型能力、响应速度、内存占用和功耗之间反复权衡。没有完美的方案只有最适合你当前场景的选择。对于教育演示、离线轻量问答、特定领域的代码补全这个方案是可行且有趣的。但对于需要高响应、长上下文的生产环境它显然力不从心。不过这个过程本身带来的对模型部署、硬件性能、量化技术以及Linux系统调优的理解是任何理论教程都无法替代的。最后一个小技巧给你的Jetson Nano配一个主动散热风扇和一个可靠的5V 4A电源它能让你在调试的路上走得更稳当。

相关资讯