当前位置: 首页 > ai >正文

Nvidia Orin DK 本地 ollama 主流 20GB 级模型 gpt-oss, gemma3, qwen3 部署与测试

这个博客用来记录在 Nvidia Orin 64 GB DK 设备上本地 ollama 部署并评测主流的几个 20GB 以下模型 gpt-oss:20bgemma3:27bqwen3:30b 模型的性能,其中 gpt-oss 是 OpenAI 刚刚开源(2025年08月05日)的模型,距离博客形成时间(2025年08月07日)仅过去 2 天,算是赶了一个大早。

如果你拿到的是一台全新的 Orin 设备,并且手上准备好了一块 M.2 接口的 SSD,那么可以参考我的这篇博客先对设备进行刷机:

  • Nvidia Orin DK 刷机CUDA TensorRT+硬盘扩容+ROS+Realsense+OpenCV+Ollama+Yolo11 一站式解决方案

首先说几个重要事项:

  1. 为了能更好的体现模型的真实状态,在测试的时候不提供任何系统提示词,系统提示词会显著影响模型输出token速率
  2. Jetson Orin 无法运行 gpt-oss:120b,128GB 显存的 Thor 能否运行我们将在收到货之后进行测试,预计在 09月04日完成评测;
  3. 在测试过程中发现 qwen3:27b 容易出现中文输入一半后突然开始输出英文的情况,并且发生了无限循环输出固定语句的事件,导致该轮测试中断;

Step1. 软硬件确认

在正式开始之前先确认软硬件配置,特别是 CUDA 和 cuDNN 版本信息,可以通过下面的命令查看相关版本信息:

$ jetson_release

在这里插入图片描述

OpenAI 开出来的模型 gpt-oss 目前有 2 个参数总量的版本,Orin 只能运行其中的 20b 参数版本,强行运行 120b 的模型会导致宕机。OpenAI 还提供了 Ollama 的模型格式,可以通过下面的链接进入 Ollama 官网查看模型:

  • Ollama - GPT-oss:https://ollama.com/library/gpt-oss

在这里插入图片描述


Step2. 安装与更新 Ollama

【Note】:必须使用最新版本的 Ollama,旧版本无法运行

如果你在之前没有下载过 Ollama,那么可以直接在官网上使用其提供的命令进行下载,亲测 Arm 上也能直接使用:

  • Ollama 官方下载页面:https://ollama.com/download/linux

在这里插入图片描述

$ curl -fsSL https://ollama.com/install.sh | sh

Step3. [重要] 修改模型默认存放路径

由于 Orin 64 GB 版本在完成刷机之后就只剩下 30 GB 左右,而本次测试至少需要有 超过 50 GB 的硬盘空间用来存储模型,因此强烈建议在执行模型拉取之前先修改 Ollama 默认存储路径。如果你之前是按照我的刷机博客完成的刷机并扩充了硬盘,那么这一步 仍然需要作,因为 ollama 模型的默认存储位置是在 /usr/share/ollama/.ollama/models,这个路径并没有挂载到硬盘上。

  1. 停止 olama 服务,这一步很重要否则不会生效
$ sudo systemctl stop ollama.service
  1. 创建一个保存模型的文件夹并修改权限,这里以 Downloads/ollama 为例:
$ cd Downloads
$ mkdir -p ollama/models$ sudo chown -R root:root /home/orin/Downloads/ollama/models
$ sudo chmod -R 777 /home/orin/Downloads/ollama/models
  1. 修改 /etc/systemd/system/ollama.service 文件:
$ sudo vim /etc/systemd/system/ollama.service

[Service] 部分添加以下内容并修改 UserGroup

User = root
Group = root
Environment="OLLAMA_MODELS=/home/orin/Downloads/ollama/models"
Environment="OLLAMA_HOST=0.0.0.0:11434"

效果如下:

在这里插入图片描述


Step4. [可选] 安装 ChatBox

ChatBox 是一个用户友好的可视化软件,使用该工具也能调用本地 ollama 模型。

【注意】:实验发现官网最新的软件无法运行,会报错 libsql 库缺失,我们在网盘中存放了一个可使用的版本,如果你从官网下载的版本可以运行则优先使用官网稳定版:

  • ChatBox 官网下载页面:https://chatboxai.app/en#download
  • 网盘:https://pan.baidu.com/s/14C2z23Ia0cqI5nwp4efI8w?pwd=6uit

下载好后赋予可执行权限后运行:

$ chmod +x Chatbox-1.15.2-alpha.0-arm64
$ ./Chatbox-1.15.2-alpha.0-arm64

在这里插入图片描述

在窗口右侧添加你的本地 ollama 模型即可。


Step5. 拉取模型

使用下面的命令拉取 gpt-oss:20bgemma3:27bqwen3:30b 模型:

$ ollama pull gpt-oss:20b
$ ollama pull gemma3:27b
$ ollama pull qwen3:30b

Step6. 模型测试脚本

受到资源限制,这里只对以下几个指标进行测试,重点考察模型的推理效率和响应速度。

  • 首字延迟 (Time to First Token, TTFT);
  • 生成速度 (Tokens Per Second, TPS);
  • 推理延迟 (Latency);
  • 吞吐量 (Throughput);

建议新建一个 conda 环境并安装 ollama 后进行测试:

(base) $ conda env create -n ollama python=3.12
(base) $ conda activate ollama
(ollama) $ pip install ollama requests

测试内容

  • prompts.jsonl
{"id": 1, "prompt": "请用Python编写一个函数,该函数接收一个未排序的整数列表,并使用归并排序(Merge Sort)算法将其排序。请在代码中加入详细的注释,解释算法的关键步骤。"}
{"id": 2, "prompt": "假设有三个盒子,一个装满了金币,另外两个是空的。每个盒子上都贴着一张标签,分别写着“金币在这里”、“金币不在这里”、“金币在第二个盒子”。但你被告知,这三张标签全部都是错的。请问,金币到底在哪个盒子里?请详细说明你的推理过程。"}
{"id": 3, "prompt": "以“当最后一个星系的光芒熄灭时,宇宙的图书管理员合上了他的书。”为开头,写一个不超过500字的科幻短篇故事。"}
{"id": 4, "prompt": "请解释什么是“黑洞信息悖论”(Black Hole Information Paradox)?这个悖论的核心矛盾是什么?目前物理学界有哪些主流的理论或假说试图解决这个悖论?"}
{"id": 5, "prompt": "你现在是一位经验丰富的市场策略师。一家新兴的电动汽车公司准备进入竞争激烈的北美市场,他们的主要卖点是创新的电池技术和可持续的生产理念。请为这家公司制定一份市场进入策略(Go-to-Market Strategy),包括目标客户群体、品牌定位、营销渠道和关键的头三个月行动计划。"}
{"id": 6, "prompt": "比较并对比两种现代编程语言:Go 和 Rust。请从以下几个方面进行分析:内存管理、并发模型、性能、生态系统和最适合的应用场景。"}
{"id": 7, "prompt": "请将以下这首李白的《月下独酌·其一》翻译成具有诗意的英文。不仅要翻译字面意思,还要尽可能传达原诗的意境和情感。\n\n花间一壶酒,独酌无相亲。\n举杯邀明月,对影成三人。\n月既不解饮,影徒随我身。\n暂伴月将影,行乐须及春。\n我歌月徘徊,我舞影零乱。\n醒时同交欢,醉后各分散。\n永结无情游,相期邈云汉。"}
{"id": "8", "prompt": "对于一个完全没有编程基础的成年人,如果他想在一年内转行成为一名前端开发工程师,请为他设计一个为期12个月的详细学习路线图。请将路线图按季度划分,并列出每个季度需要学习的关键技术栈、建议的实践项目和评估学习成果的方法。"}
{"id": 9, "prompt": "请以通俗易懂的方式,向一名高中生解释什么是“零知识证明”(Zero-Knowledge Proof)。可以举一个具体的例子,比如“阿里巴巴的洞穴”或者其他类似的例子来帮助理解。"}
{"id": 10, "prompt": "分析自动驾驶汽车在面临“电车难题”(Trolley Problem)时的道德和伦理困境。例如,当不可避免的碰撞发生时,汽车应该优先保护乘客,还是优先保护行人?如果需要做出选择,它的决策依据应该是什么?讨论一下当前业界和学术界对这个问题的不同观点。"}

测试脚本

  • benchmark.py
import ollama
import json
import time
import statistics# --- 配置 ---
MODEL_NAME = "gpt-oss:20b"
PROMPTS_FILE = "prompts.jsonl"def benchmark_model_with_library():"""使用官方 ollama 库进行基准测试。这个版本更健壮,并解决了之前遇到的所有问题。"""results = []print(f"🚀 开始对模型 '{MODEL_NAME}' 进行基准测试 (使用 ollama 库)...")print(f"🔄 从文件 '{PROMPTS_FILE}' 加载 prompts...")try:with open(PROMPTS_FILE, 'r', encoding='utf-8') as f:prompts = [json.loads(line) for line in f]except FileNotFoundError:print(f"❌ 错误: prompts文件 '{PROMPTS_FILE}' 未找到。")returnexcept json.JSONDecodeError:print(f"❌ 错误: '{PROMPTS_FILE}' 文件格式不正确。")returnprint(f"✅ 成功加载 {len(prompts)} 个 prompts。\n")for i, item in enumerate(prompts):prompt_id = item.get("id", i + 1)prompt_text = item.get("prompt")if not prompt_text:print(f"⚠️ 警告: 第 {prompt_id} 个prompt为空,已跳过。")continueprint(f"--- [ Prompt {prompt_id}/{len(prompts)} ] ---")print(f"🤔 输入: {prompt_text[:80]}...")print(f"\n模型输出: ", end="")messages = [{'role': 'user', 'content': prompt_text}]try:start_time = time.time()first_token_time = Nonelast_token_time = Nonetoken_count = 0is_first_chunk = True# 使用 ollama.chat 进行流式请求stream = ollama.chat(model=MODEL_NAME,messages=messages,stream=True,)for chunk in stream:# 记录首个Token时间if is_first_chunk:first_token_time = time.time()is_first_chunk = False# 流式打印内容content = chunk['message']['content']print(content, end='', flush=True)# 记录最后一个Token的时间点last_token_time = time.time()# 检查是否是最后一个数据块,并从中获取最终的token计数if chunk.get('done'):# 'eval_count' 是Ollama返回的生成token数量token_count = chunk.get('eval_count', 0)end_time = time.time()print("\n") # 换行if token_count == 0 or first_token_time is None:print("⚠️ 模型没有生成任何有效的token。")continue# --- 指标计算 ---ttft = first_token_time - start_timee2e_latency = end_time - start_time# 因为我们现在有了准确的token_count,所以ITL和TPS的计算会更精确if token_count > 1:# ITL 使用 last_token_time 更精确,因为它代表最后一个内容块的时间itl = (last_token_time - first_token_time) / (token_count - 1)else:itl = 0.0tps = token_count / e2e_latencyresult = {"id": prompt_id, "ttft": ttft, "e2e_latency": e2e_latency, "itl": itl, "tps": tps, "token_count": token_count}results.append(result)print(f"✅ 完成! 生成了 {token_count} 个 tokens。")print(f"   - TTFT (首个Token生成时间): {ttft:.4f} 秒")print(f"   - E2E Latency (端到端延迟): {e2e_latency:.4f} 秒")print(f"   - ITL (Token间延迟): {itl * 1000:.4f} 毫秒/token")print(f"   - TPS (每秒生成Token数): {tps:.2f} tokens/秒\n")except Exception as e:print(f"\n❌ 在处理过程中发生未知错误: {e}")continue# --- 汇总结果 (这部分无需改动) ---if results:print("\n--- 📊 基准测试汇总报告 ---")avg_ttft = statistics.mean([r['ttft'] for r in results])avg_e2e_latency = statistics.mean([r['e2e_latency'] for r in results])avg_itl = statistics.mean([r['itl'] for r in results])avg_tps = statistics.mean([r['tps'] for r in results])total_tokens = sum([r['token_count'] for r in results])print(f"测试模型: {MODEL_NAME}")print(f"测试数量: {len(results)} 个 prompts")print(f"生成总数: {total_tokens} 个 tokens")print("\n--- 平均性能指标 ---")print(f"平均 TTFT: {avg_ttft:.4f} 秒")print(f"平均 E2E Latency: {avg_e2e_latency:.4f} 秒")print(f"平均 ITL: {avg_itl * 1000:.4f} 毫秒/token")print(f"平均 TPS: {avg_tps:.2f} tokens/秒")print("--------------------------\n")if __name__ == "__main__":benchmark_model_with_library()

执行测试

为了正确体现模型的性能,避免从硬盘加载模型耗时被错误统计进来,你可以先使用下面的脚本 single_test.py 先激活测试模型:

from ollama import chat
from ollama import ChatResponsestream = chat(model='gpt-oss:20b',messages=[{'role': 'user', 'content': '为什么天空是蓝色的?'}],stream=True,
)for chunk in stream:print(chunk['message']['content'], end='', flush=True)
(ollama) $ python load_model_demo.py

jtop 命令查看 GPU 显存的使用状态,执行后在键盘上敲击数字 2 即可查看显存的动态加载情况:

$ jtop

在这里插入图片描述

在确认模型已经加载后执行测试脚本:

(ollama) $ python benchmark.py

在这里插入图片描述

在这里插入图片描述


测试结果

单一模型测试

测试指标gpt-oss:20bgemma3:27bqwen3:30b
TTFT (首个Token生成时间)1.3572 秒1.6511 秒0.5238 秒
E2E Latency (端到端延迟)215.4739 秒165.4303 秒170.5114 秒
ITL (Token间延迟)86.2675 毫秒/token141.8144 毫秒/token43.1018 毫秒/token
TPS (每秒生成Token数)11.48 tokens/秒6.99 tokens/秒23.16 tokens/秒

横向评测

这部分选择了 qwen3:30b(19GB)和 gpt-oss:20b(14GB)进行了对比,询问了以下问题,并将两个模型回答结果发送给 Gemini 2.5 Pro在线模型进行打分(0~10分),同时要求给出理由:

Gemini 2.5 Pro 模型的系统提示词如下:

你是一个客观公正的大语言模型质量评判专家,我需要你你对多个本地模型输出的内容质量进行打分(0-10分)并给出理由,由于模型之间的参数量相当,因此他们的回答可能比较接近,你需要从更抽象层面出发进行评判。我将以文件的形式为你提供不同模型的回答。
  • 问题一:
请用Python编写一个函数,该函数接收一个未排序的整数列表,并使用归并排序(Merge Sort)算法将其排序。请在代码中加入详细的注释,解释算法的关键步骤。
  • 问题二:
假设有三个盒子,一个装满了金币,另外两个是空的。每个盒子上都贴着一张标签,分别写着“金币在这里”、“金币不在这里”、“金币在第二个盒子”。但你被告知,这三张标签全部都是错的。请问,金币到底在哪个盒子里?请详细说明你的推理过程。
  • 问题三:
以“当最后一个星系的光芒熄灭时,宇宙的图书管理员合上了他的书。”为开头,写一个不超过500字的科幻短篇故事。
  • 问题四:
请解释什么是“黑洞信息悖论”(Black Hole Information Paradox)?这个悖论的核心矛盾是什么?目前物理学界有哪些主流的理论或假说试图解决这个悖论?
  • 问题五:
你现在是一位经验丰富的市场策略师。一家新兴的电动汽车公司准备进入竞争激烈的北美市场,他们的主要卖点是创新的电池技术和可持续的生产理念。请为这家公司制定一份市场进入策略(Go-to-Market Strategy),包括目标客户群体、品牌定位、营销渠道和关键的头三个月行动计划。

所有测试样本与评判结果都保存在了网盘中:

https://pan.baidu.com/s/14C2z23Ia0cqI5nwp4efI8w?pwd=6uit

Gemini 2.5 Pro 评判分结果如下:

gpt-oss:20b - 13GBgemma3:27b - 17GBqwen3:30b - 18GB
问题一9.78.09.2
问题二9.57.53.0
问题三9.88.66.5
问题四9.87.88.5
问题五9.67.28.8
http://www.xdnf.cn/news/19906.html

相关文章:

  • AI搜索排名规则突变:企业如何用GEO工具保持竞争力?
  • LeetCode 刷题【64. 最小路径和】
  • 无人机气象观测技术
  • 华为的 4A 架构简介
  • 代码随想录算法训练营第二十八天 | 买卖股票的最佳实际、跳跃游戏、K次取反后最大化的数组和
  • Vue基础知识-脚手架开发-初始化目录解析
  • 分布式对象存储系统 Minio 之 Centos 环境安装
  • SQLynx 3.7 发布:数据库管理工具的性能与交互双重进化
  • Java 方法:从定义调用到重载,入门到面试全攻略
  • 前端路由切换不再白屏:React/Vue 实战优化全攻略(含可运行 Demo)
  • 基于html+css+js+jquery实现轮播图(自动轮播,手动选择,翻页)
  • #T1359. 围成面积
  • 华清远见25072班I/O学习day5
  • 嵌入式硬件 - 51单片机3
  • NotePad++下载安装与设置
  • 使用a标签跳转之后,会刷新一次,这个a标签添加的样式就会消失
  • 搞懂IFNULL 和 NULLIF
  • 【C++详解】异常概念、抛出捕获与处理机制全解析
  • 一文读懂数据分类分级:企业安全治理的基石
  • 深入理解Linux进程信号机制
  • 残差神经网络的案例
  • 【面试题】LangChain与LlamaIndex核心概念详解
  • 聚焦GISBox矢量服务:数据管理、数据库连接与框架预览全攻略
  • 分布式电源接入电网进行潮流计算
  • Linux笔记---UDP套接字实战:简易聊天室
  • 服务器不支持node.js16以上版本安装?用Docker轻松部署Node.js 20+环境运行Strapi项目
  • 新规则,新游戏:AI时代下的战略重构与商业实践
  • 安全领域必须关注每年发布一次“最危险的25种软件弱点”清单 —— CWE Top 25(内附2024 CWE Top 25清单详情)
  • Boost搜索引擎 数据清洗与去标签(1)
  • 【OpenHarmony文件管理子系统】文件访问接口mod_fs解析