1. 为什么要在 4GB 显存的小板子上死磕大模型手里攥着一块 4GB 显存的 Jetson Orin Nano想跑大模型这件事本身就带着一股吃土的气质。我第一次把板子点亮、SSH 进去、敲下nvidia-smi看到那可怜的显存数字时心里是有点发怵的——现在随便一个 7B 的模型FP16 权重就要 14GB 左右4GB 连零头都不够。但现实需求摆在那儿边缘设备要离线推理、要低延迟、要数据不出本地云端 API 那套方案在工业现场、隐私敏感场景里根本走不通。所以问题不是要不要跑而是怎么在 4GB 里把它塞进去还能跑得动。这篇文章记录的就是我在这块小板子上折腾大模型的完整过程我把它拆成三部曲抠内存、塞模型、养 Agent。抠内存是把系统层面能省的全省下来给模型腾地方塞模型是选对量化格式和推理框架把大模型压进 4GB养 Agent 是在能跑通推理的基础上搭一个真正能干活的智能体。整套流程围绕 Jetson Orin Nano、llama.cpp、GGUF、Agent 这几个关键词展开适合手里有 Jetson 系列板子、想在边缘端做本地大模型推理和智能体开发的人参考。不管你是刚拿到板子的新手还是已经跑过几轮推理的老手这里面的踩坑记录和参数取舍应该都能帮你少走点弯路。先说结论免得你看到一半发现方向不对4GB 显存跑 7B 级别的模型靠的是4-bit 量化 llama.cpp 的 GPU offload 系统内存的极限压榨能跑但别指望速度和全量精度。想要流畅的 Agent 体验模型规模得压到 3B 甚至 1.5B或者接受能跑但慢的现实。这不是劝退是让你心里有数。2. 抠内存把系统榨干之前先搞清楚显存和内存的账2.1 Jetson 的显存是共享的这是机会也是陷阱很多人第一次接触 Jetson 会懵这板子没有独立显存GPU 和 CPU 共用同一块 LPDDR5。Orin Nano 4GB 版本整块内存就 4GB系统、GPU、各种进程全从这里面分。这意味着你看到的4GB 显存其实是动态分配的不是一块独立的显存池。这个特性是双刃剑——好处是你可以通过调整分配策略让 GPU 拿到更多坏处是系统本身也要吃内存留给模型的空间比你想的还少。我实测下来刚烧录完系统、什么都没装的状态空闲内存大概在 2.8GB 左右系统本身占掉 1GB 多。等你装完 CUDA、cuDNN、各种依赖再跑个桌面环境空闲内存能掉到 1.5GB 以下。这时候你想跑模型基本没戏。所以抠内存的第一步是砍掉一切不必要的系统负担。2.2 关掉图形界面省下的内存比你想象的多Jetson 默认烧录的 JetPack 带桌面环境对开发调试方便但对跑模型是纯负担。我建议直接切到多用户命令行模式sudo systemctl set-default multi-user.target sudo reboot重启后系统不再加载 GNOME 桌面空闲内存能多出 400MB 到 600MB。别小看这几百兆在 4GB 的板子上这就是能不能多塞一层模型的关键。如果你确实需要图形界面做可视化可以装个轻量的窗口管理器或者干脆用远程 X11 转发把渲染压力丢给本地机器。除了关桌面还有几个系统服务可以关掉蓝牙、打印服务、ModemManager、avahi-daemon 这些在边缘推理场景里基本用不上。用systemctl disable挨个关掉又能挤出几十到上百兆。我整理了一份常用的关闭清单服务名作用是否建议关闭bluetooth蓝牙是cups打印是ModemManager移动网络管理是avahi-daemon局域网发现是snapd包管理是如果不用 snapunattended-upgrades自动更新是关完之后用free -h看一眼空闲内存应该能回到 2GB 以上。2.3 调整 GPU 内存分配策略Jetson 上有个nvpmodel和jetson_clocks的组合前者管功耗模式后者管频率锁定。跑模型的时候我一般把功耗模式拉到最大sudo nvpmodel -m 0 sudo jetson_clocks-m 0是最高性能模式所有核心全开。这会增加功耗和发热但推理速度能提升 20% 到 30%。如果你的板子散热一般注意加个风扇不然跑一会儿就降频了。另外CUDA 在 Jetson 上默认会预留一部分内存做缓存可以通过环境变量控制export CUDA_DEVICE_MAX_CONNECTIONS1 export CUDA_CACHE_MAXSIZE1073741824CUDA_CACHE_MAXSIZE设成 1GB 是上限实际用多少看情况。如果你的模型很小可以把这个值调低省出更多内存给模型权重。2.4 交换空间的取舍zram 还是 swap 文件内存不够的时候第一反应是加交换空间。Jetson 上可以用传统的 swap 文件也可以用 zram压缩内存块设备。我的经验是zram 更适合这种场景因为它压缩的是内存里的数据读写速度比磁盘 swap 快得多而且不占用 eMMC 或 NVMe 的寿命。配置 zram 的步骤sudo apt install zram-config sudo systemctl restart zram-config默认配置会按内存比例分配 zram 大小4GB 内存大概能压出 2GB 左右的可用空间。但要注意zram 压缩会吃 CPU如果你的模型推理已经把 CPU 占满了zram 反而会拖慢整体速度。所以我的建议是zram 用来兜底别指望它当主力。真正跑模型的时候还是要把模型权重放进物理内存和显存里。3. 塞模型GGUF 量化与 llama.cpp 的 GPU offload 实战3.1 为什么选 GGUF 而不是其他格式模型格式这块我试过 PyTorch 原生、ONNX、TensorRT、GGUF 好几种。在 4GB 的 Jetson 上GGUF 是唯一让我觉得能用的格式。原因有几个第一GGUF 支持多种量化级别从 Q2 到 Q8 都有可以按显存大小灵活选第二llama.cpp 对 GGUF 的支持最成熟GPU offload 做得好第三GGUF 是单文件格式模型权重、tokenizer、配置全打包在一起部署的时候不用折腾一堆依赖。TensorRT 理论上在 Jetson 上性能最好但转换过程太痛苦而且对模型结构有要求不是所有模型都能顺利转。ONNX 的 GPU 支持在 Jetson 上也不如 llama.cpp 直接。所以我的选择很明确GGUF llama.cpp。3.2 量化级别的选择Q4_K_M 是甜点GGUF 的量化级别很多常见的有 Q2_K、Q3_K_M、Q4_K_M、Q5_K_M、Q6_K、Q8_0。数字越小压缩越狠精度损失越大。在 4GB 显存上我的实测结论是量化级别7B 模型大小4GB 能否跑质量评价Q2_K~2.8GB勉强明显掉智不推荐Q3_K_M~3.3GB可以能用但偶尔胡言乱语Q4_K_M~4.1GB需要 offload甜点推荐Q5_K_M~4.8GB困难需要大量 offload慢Q8_0~7.2GB不可能放弃Q4_K_M 是我最推荐的级别。它在 4GB 板子上需要把一部分层 offload 到 GPU剩下的跑在 CPU 上速度大概在 5 到 8 token/s做 Agent 的推理够用了。如果你追求更高质量可以试试 Q5_K_M但要做好速度掉到 2 到 3 token/s 的心理准备。模型下载这块Hugging Face 上有很多已经量化好的 GGUF 文件直接搜模型名加 GGUF 就能找到。下载完之后放到本地目录llama.cpp 直接加载就行。3.3 编译 llama.cppJetson 上的 CUDA 支持llama.cpp 在 Jetson 上编译关键是打开 CUDA 支持。步骤不复杂但有几个坑git clone https://github.com/ggerganov/llama.cpp cd llama.cpp mkdir build cd build cmake .. -DLLAMA_CUDAON -DLLAMA_CUBLASON make -j4-DLLAMA_CUDAON打开 CUDA 支持-DLLAMA_CUBLASON启用 cuBLAS 加速。编译的时候注意-j4别开太大Jetson 的 CPU 核心有限开太多反而慢。编译完成后build/bin目录下会有llama-cli、llama-server等可执行文件。这里有个坑Jetson 的 CUDA 架构是 sm_87Orin 系列编译的时候如果 cmake 没自动识别需要手动指定cmake .. -DLLAMA_CUDAON -DCMAKE_CUDA_ARCHITECTURES87不指定的话编译出来的二进制可能跑不起来报 no kernel image is available 之类的错误。3.4 GPU offload 层数的调优llama.cpp 的-ngl参数控制有多少层 offload 到 GPU。这个参数是 4GB 板子上最关键的调优点。设得太小GPU 用不上速度慢设得太大显存爆了直接 OOM。我的调优方法是从 0 开始每次加 5 层跑一次看显存占用和速度。7B 模型一般有 32 层左右4GB 显存大概能 offload 20 到 25 层剩下的跑 CPU。具体命令./llama-cli -m models/qwen2.5-7b-instruct-q4_k_m.gguf -ngl 22 -c 2048 -n 256-c 2048是上下文长度-n 256是生成的最大 token 数。上下文长度也会吃显存2048 是个比较安全的起点想跑长上下文可以往上加但显存会跟着涨。实测下来-ngl 22的时候显存占用大概在 3.6GB 左右留了 400MB 余量给系统。速度在 6 token/s 上下做简单的问答和 Agent 推理够用。如果你把-ngl拉到 25显存直接顶到 3.9GB系统开始卡顿偶尔会 OOM。所以留余量很重要别把显存吃满。3.5 小模型的选择3B 和 1.5B 才是 Agent 的归宿7B 模型在 4GB 板子上能跑但跑 Agent 的时候会很吃力。Agent 需要多轮推理、工具调用、上下文管理每一轮都要吃 token7B 的速度撑不住。所以我的建议是Agent 场景用 3B 或 1.5B 的模型。Qwen2.5 系列有 3B 和 1.5B 的版本量化到 Q4_K_M 之后3B 大概 2GB1.5B 大概 1GB。这两个尺寸在 4GB 板子上可以全量 offload 到 GPU速度能到 15 到 25 token/s做 Agent 的响应速度就舒服多了。质量上3B 模型做简单的工具调用和问答没问题复杂推理会弱一些但边缘场景本来就不追求 GPT-4 级别的能力。4. 养 Agent在 4GB 板子上搭一个能干活的智能体4.1 Agent 和普通推理的区别多轮、工具、记忆跑通模型推理只是第一步Agent 的核心在于多轮交互、工具调用和记忆管理。普通推理是你问一句它答一句Agent 是你给个目标它自己规划步骤、调用工具、根据结果调整。这中间的差别对资源的需求完全不是一个量级。多轮交互意味着上下文会不断增长KV cache 占的显存越来越多。工具调用意味着模型要输出结构化的 JSON对模型的指令遵循能力有要求。记忆管理意味着你要在本地存对话历史、工具结果还要做检索。这些在 4GB 板子上都要精打细算。4.2 用 llama.cpp 的 server 模式做 Agent 后端llama.cpp 自带llama-server可以起一个兼容 OpenAI API 的 HTTP 服务。这是搭 Agent 最省事的方式./llama-server -m models/qwen2.5-3b-instruct-q4_k_m.gguf -ngl 99 -c 4096 --host 0.0.0.0 --port 8080-ngl 99表示所有层都 offload 到 GPU3B 模型在 4GB 显存上可以全量 offload。-c 4096是上下文长度Agent 场景建议至少 4096不然多轮对话很快就满了。server 起来之后你的 Agent 框架就可以通过 HTTP 请求调用模型跟调 OpenAI API 一样。这样 Agent 的逻辑可以用 Python、Node.js 随便写模型推理交给 llama.cpp。4.3 Agent 框架的选择轻量优先Agent 框架这块LangChain、AutoGPT、CrewAI 这些主流的我都试过但在 4GB 板子上越轻量越好。LangChain 功能全但依赖重跑起来内存占用不小。我的建议是自己写一个简单的 Agent 循环或者用极简的框架。一个最简 Agent 循环大概长这样import requests import json def call_model(messages): resp requests.post(http://localhost:8080/v1/chat/completions, json{ messages: messages, temperature: 0.7, max_tokens: 512 }) return resp.json()[choices][0][message][content] def agent_loop(user_input): messages [{role: system, content: 你是一个助手可以调用工具。}, {role: user, content: user_input}] while True: reply call_model(messages) if 工具调用 in reply: # 解析工具调用执行把结果加回 messages pass else: return reply这个循环很粗糙但核心逻辑就是模型输出 - 判断是否要调工具 - 执行工具 - 结果喂回模型 - 继续。在 4GB 板子上这种极简实现比拖一堆依赖的框架靠谱得多。4.4 工具调用的提示词设计小模型的指令遵循能力有限工具调用的提示词要写得非常明确。我的经验是用 JSON schema 约束输出格式并且在 system prompt 里给例子。比如你要让模型调用一个查天气的工具system prompt 可以这么写你可以调用以下工具 - get_weather(city: str): 查询城市天气 调用工具时输出格式必须是 {tool: get_weather, args: {city: 北京}} 如果不需要调用工具直接回答用户问题。然后在代码里解析模型的输出如果是 JSON 就执行工具否则当普通回复。小模型偶尔会输出格式不对的 JSON所以解析的时候要做容错解析失败就当成普通回复处理。4.5 记忆管理别让上下文爆掉Agent 跑多轮之后上下文会越来越长最终撑爆-c设的上限。解决办法有两个滑动窗口和摘要压缩。滑动窗口最简单只保留最近 N 轮对话老的直接丢掉。实现上就是在构造 messages 的时候只取最后几条。缺点是会丢失早期信息。摘要压缩稍微复杂当上下文超过阈值时让模型把前面的对话总结成一段话用摘要替换原始对话。这样能保留关键信息但多了一次模型调用速度会慢一点。在 4GB 板子上我一般用滑动窗口简单可靠。如果任务确实需要长期记忆可以把对话历史存到本地文件或 SQLite需要的时候检索出来而不是全塞进上下文。4.6 Agent 的实测表现与调优我用 Qwen2.5-3B 在 Orin Nano 4GB 上跑了一个简单的 Agent任务是查天气并给出穿衣建议。实测下来单轮工具调用的延迟在 2 到 3 秒多轮任务大概 10 到 15 秒完成。这个速度在边缘场景可以接受但离流畅还有距离。调优的方向有几个降低 max_tokensAgent 的输出不需要太长256 够用、减少工具数量工具越多模型选择越容易出错、优化提示词越简洁明确越好。另外llama-server支持--parallel参数做并发但 4GB 板子上并发会抢显存不建议开。5. 踩坑记录那些让我熬夜的报错和解决过程5.1 编译 llama.cpp 报 CUDA 架构不匹配第一次编译的时候cmake 没识别出 Jetson 的 CUDA 架构编译出来的二进制跑起来报 no kernel image is available for execution on the device。排查了半天最后发现是CMAKE_CUDA_ARCHITECTURES没设对。Orin 系列是 sm_87需要在 cmake 命令里显式指定cmake .. -DLLAMA_CUDAON -DCMAKE_CUDA_ARCHITECTURES87如果你用的是其他 Jetson 型号架构号不一样Nano 是 sm_53Xavier 是 sm_72Orin 是 sm_87。设错了就是跑不起来。5.2 模型加载到一半 OOM这个坑我踩了好几次。表现是 llama.cpp 加载模型的时候进度条走到一半突然报 out of memory。原因是-ngl设得太大显存不够。解决办法是先把-ngl设小跑起来之后再慢慢往上加。另外加载模型的时候系统本身也在吃内存如果后台有别的进程也会抢。加载前用free -h确认一下空闲内存不够就先关掉不必要的进程。5.3 Agent 调用工具时 JSON 解析失败小模型输出 JSON 的时候经常会多输出一些废话比如 好的我来调用工具{...}导致 JSON 解析失败。我的解决办法是用正则从输出里提取 JSON 部分而不是直接json.loads整个输出。正则大概长这样import re match re.search(r\{.*\}, reply, re.DOTALL) if match: tool_call json.loads(match.group())这样即使模型多说了几句也能把 JSON 抠出来。如果正则也匹配不到就当成普通回复处理。5.4 长时间运行后系统变卡Agent 跑久了之后系统会越来越卡最后连 SSH 都响应慢。原因是内存碎片和缓存积累。解决办法是定期重启 llama-server或者用sync echo 3 /proc/sys/vm/drop_caches清理缓存。另外Agent 的对话历史如果一直存在内存里也会越积越多记得做滑动窗口或者定期清理。6. 从能跑到好用几个让体验提升的细节6.1 用 systemd 管理 llama-server每次手动起 server 太麻烦用 systemd 做成服务开机自启[Unit] Descriptionllama-server Afternetwork.target [Service] ExecStart/home/user/llama.cpp/build/bin/llama-server -m /home/user/models/qwen2.5-3b-q4_k_m.gguf -ngl 99 -c 4096 --host 0.0.0.0 --port 8080 Restartalways Useruser [Install] WantedBymulti-user.target存到/etc/systemd/system/llama-server.service然后systemctl enable --now llama-server。这样板子一开机模型服务就起来了Agent 直接调就行。6.2 监控显存和温度跑 Agent 的时候显存和温度要盯着。tegrastats是 Jetson 自带的监控工具能看到显存、CPU、GPU、温度tegrastats --interval 1000输出里GR3D_FREQ是 GPU 频率RAM是内存占用tj是结温。结温超过 80 度就要注意散热了超过 90 度会降频。我一般会在 Agent 代码里加个监控线程温度过高就暂停任务等降温再继续。6.3 模型文件的存放位置GGUF 模型文件建议放在 NVMe SSD 上别放 eMMC。eMMC 的读写速度慢加载模型的时候会拖很久。Orin Nano 有 M.2 接口插个 NVMe 固态模型加载速度能快好几倍。如果只能用 eMMC那就把模型文件放在内存盘tmpfs里但 4GB 内存放模型文件不太现实所以还是建议上 NVMe。6.4 关于 Ollama 的取舍很多人问能不能用 Ollama 跑 GGUF。Ollama 确实方便但它对 Jetson 的 GPU 支持不如 llama.cpp 直接而且 Ollama 本身也吃内存。在 4GB 板子上我建议直接用 llama.cpp省掉 Ollama 这层开销。如果你已经在用 Ollama可以把 GGUF 模型导入进去但性能上不如原生 llama.cpp。7. 这套方案能做什么不能做什么7.1 适合的场景这套 4GB 板子跑大模型 Agent 的方案适合离线、低延迟、隐私敏感的边缘场景。比如工业设备的本地语音助手、家庭自动化的本地控制中枢、野外设备的离线问答。这些场景对模型能力要求不高但对响应速度和数据本地化要求高正好是这套方案的强项。7.2 不适合的场景如果你需要复杂推理、长上下文、高质量生成4GB 板子撑不住。7B 模型在 4GB 上跑 Q4 量化质量已经打了折扣再往上做复杂任务错误率会明显上升。这种场景还是得上更大显存的设备或者用云端 API。7.3 后续可以扩展的方向如果后面换了更大显存的板子比如 Orin NX 16GB 或 AGX Orin这套方案可以直接迁移只需要把-ngl调大、换更大的模型。Agent 的逻辑不用改llama-server 的接口也不变。所以现在在 4GB 上踩的坑都是在为后面铺路。我个人在实际操作中的体会是4GB 跑大模型核心不是能不能跑而是怎么跑得稳。抠内存、塞模型、养 Agent 这三步每一步都有取舍每一步都要留余量。别追求极限留 10% 到 20% 的余量给系统比把显存吃满然后频繁 OOM 要靠谱得多。最后再分享一个小技巧如果你发现模型加载特别慢检查一下模型文件是不是放在 eMMC 上换到 NVMe 上加载速度能快 3 到 5 倍这个提升比调任何参数都明显。
企业数字化 ERP 产品动态
相关推荐
MyBatis动态SQL全解析:从条件拼接到标签化实践 如果你写过多条件查询,大概率经历过这样的场景:一个列表筛选页,筛选条件有七八个,每个都可选可不选,于是你在Java代码里一层层嵌套if去拼SQL字符串。先判断参数是不是null,再判断是不是空字符串,… · 2026/9/24 22:37:01
从提示词堆砌到技能模块化:AI Agent开发实战 我做了两年多 AI Agent 相关的开发,踩过最大的坑,就是把 Agent 的能力全堆在提示词里。一开始觉得挺爽,prompt 里写清楚“你可以调用搜索、计算、写代码”,模型好像真的听话。等任务稍微复杂点就原形毕露:上下文被占满… · 2026/9/24 22:37:01
热修复原理与实战:从Android Tinker到后端Arthas 线上这周已经崩了三次,客户在群里拍桌子,你最想干的事是什么?大部分人第一反应是:赶紧把出问题的代码修掉,最好能立刻生效。这就是“热修复”这门技术存在的意义——在不下发完整新版本的情况下,让已经在线… · 2026/9/24 22:37:01
开源工业网关实战:西门子S7 PLC转MQTT低成本上云方案 1. 为什么工业现场需要开源网关1.1 从一条产线改造需求说起去年帮朋友的小型注塑车间做数字化改造,现场有六台西门子 S7-200 SMART 和两台 S7-1200,老板的要求很朴素:在办公室的大屏上能看到每台设备的实时运行状态,手机也能随时瞄… · 2026/9/24 23:15:41
开源工业网关实战:S7协议直连西门子PLC与MQTT上云 1. 为什么要在工控现场折腾一个开源网关车间里那台西门子 S7-1200 已经稳定跑了三年,产线数据一直锁在 PLC 里出不来。老板突然说要搞数字化看板,要实时看到设备运行状态,还要把数据推到云端做分析。找原厂方案报价,一套下来小十万… · 2026/9/24 23:15:41
老旧设备物联网改造:Modbus转MQTT网关选型与实操指南 1. 老旧设备接入物联网的真实困境车间里那台2008年投产的注塑机还在稳定运行,PLC是西门子S7-200,通信口只有一个RS-485,跑的是Modbus RTU。现在老板要求把它的运行状态、产量计数、故障报警全部上传到云端管理平台,平台那边只认MQ… · 2026/9/24 23:15:41
工业边缘计算:实时性、确定性与鲁棒性的三笔硬账 1. 三笔账不是比喻,是现场工程师每天要填的工单“工业现场为什么需要边缘计算控制器?”——这个问题如果扔给产线老师傅,他大概率会抬头看看头顶嗡嗡响的PLC柜,再指指隔壁车间刚换上的新触摸屏,说一句:“不… · 2026/9/24 23:15:41
Paho MQTT升级实战:从1.2.0到1.2.5的迁移与避坑指南 MQTT是物联网项目里绕不开的传输协议,而Paho MQTT作为Python生态里最常用的客户端库,版本升级是每个正式项目都躲不掉的事。最近我正好把项目里的Paho MQTT从1.2.0升级到1.2.5,整个过程看着像一次小版本迭代,实际动起手来才发现坑… · 2026/9/24 23:15:35
Qt+FFmpeg实现RTSP取流显示:从环境搭建到性能调优 简介:面向Qt环境下流媒体应用开发者的RTSP取流资源,以FFmpeg库为核心,解决在Qt中拉取RTSP视频流、解码并播放的实际问题,适合C/Qt中高级开发者及多媒体入门学习者参考。压缩包共158个文件,包含115个头文件、3个C源文件… · 2026/9/24 23:15:35
基于YOLOv8的渔船作业监控系统:从环境搭建到边缘部署全流程 简介:这是一套面向计算机、人工智能、自动化等专业学生与教师的毕业设计级项目资源,围绕YOLOv8实现渔船作业监控系统,可用于毕设、课程设计、大作业或项目立项演示。压缩包共97个文件,约24.21MB,以70个Python源码文件为… · 2026/9/24 0:00:13
1D-CNN时间序列建模实战:从Conv1d原理到工业落地 简介:面向时间序列数据建模的一维卷积神经网络完整实现,适合深度学习入门者及需要快速验证时序模型的研究者,能够从音频、文本、传感器或股价等序列中挖掘局部特征与时间依赖。压缩包体积很小,只有3KB,内含3个Python脚… · 2026/9/24 0:00:26
柔软的L:汉语语流中被忽视的舌肌张力控制 1. 这个“L”不是字母表里的L,而是舌尖上的L最近在几个方言群和语音教学社群里,反复看到有人发一句:“也说字母L:柔软的长舌”。初看以为是英语发音课笔记,点开才发现全是方言爱好者、播音系学生、语言康复师甚至戏曲演… · 2026/9/24 0:00:44