跳到主要内容

Linux/GPU/Jetson 工具链基础

学习目标

  • 掌握 Ubuntu Server 上跑端侧/本地推理实验所需的基本工具链。
  • 理解 NVIDIA driver, CUDA runtime/toolkit, CMake, Python 环境和容器之间的关系。
  • 理解 Jetson 上 JetPack, Jetson Linux, tegrastats, nvpmodel 和功耗模式的作用。
  • 能构建和运行 llama.cpp CUDA 后端, 并判断 GPU offload 是否生效。
  • 能保存可复查的环境信息, 避免实验不可复现。
提示

本章的目标不是把学员训练成 Linux 运维或 CUDA 工程师, 而是让学员能独立完成端侧模型部署实验的环境检查, 构建, 运行和日志保存。

问题背景

推理框架经常依赖系统级组件。驱动, CUDA, CMake, 编译器, Python 包和动态库路径任何一个环节错了, 都可能表现成“模型慢”, “GPU 没用上”, “构建失败”或“服务启动后立刻退出”。

课程实作采用两条硬件路径:

  • Ubuntu Server + NVIDIA GPU: 用于建立可重复的 Qwen 小模型部署基线, 适合先做量化和推理加速对比。
  • NVIDIA Jetson: 用于观察边缘设备约束, 包括共享内存, 功耗模式, 温度, 散热和 JetPack 版本差异。

这两条路径都不是“安装完就结束”。学员需要能回答:

  • GPU 是否被系统识别?
  • runtime 是否编译了 CUDA 后端?
  • 模型运行时是否真的 offload 到 GPU?
  • 显存或内存峰值如何记录?
  • Jetson 当前功耗模式是什么?
  • 实验结果能否被别人复现?

图示讲解

Ubuntu Server 推理工具链

Jetson 推理工具链

问题定位路径

核心概念

NVIDIA Driver

Driver 让操作系统识别并调度 NVIDIA GPU。服务器上常用 nvidia-smi 查看驱动和 GPU 状态。驱动不可用时, 上层 CUDA 和推理框架通常也无法正常使用 GPU。

关键检查:

nvidia-smi

关注:

  • GPU 型号。
  • Driver Version。
  • CUDA Version 字段。
  • 显存总量和当前占用。
  • 当前运行的 GPU 进程。
备注

nvidia-smi 中显示的 CUDA Version 表示驱动支持的 CUDA 运行能力上限, 不等同于本机安装了完整 CUDA toolkit。

CUDA Runtime 与 CUDA Toolkit

CUDA runtime 是运行 GPU 程序所需的库。CUDA toolkit 包含编译器 nvcc, 头文件和开发工具。很多部署场景只需要 runtime, 但编译 llama.cpp CUDA 后端时通常需要相应开发环境。

检查:

nvcc --version
ldconfig -p | grep cuda || true

如果 nvcc 不存在, 不一定代表 GPU 不能运行已有程序, 但可能影响从源码构建 CUDA 后端。

CMake 与编译器

llama.cpp 等本地推理项目通常使用 CMake 构建。课程中重点关注构建参数是否启用了 CUDA 后端。

cmake --version
gcc --version || clang --version

Python 环境

Python 在本课程中主要用于:

  • 调用本地 API。
  • 做环境 smoke test。
  • 处理 profiling 结果表。
  • 使用 Transformers 检查 tokenizer 和 chat template。

不要把模型权重, 下载缓存和虚拟环境提交到课程仓库。建议实验目录放在 ~/edge-ai-lab

Container

容器可以减少环境差异, 但也会引入 GPU 权限和挂载问题。使用容器时要确认:

  • 宿主机 driver 正常。
  • NVIDIA Container Toolkit 已安装。
  • 容器启动参数允许访问 GPU。
  • 模型目录和结果目录正确挂载。

本课程先以宿主机原生运行建立基础, 再把容器作为可选扩展。

JetPack 与 Jetson Linux

JetPack 是 Jetson 的软件栈集合, 通常包含 Jetson Linux, CUDA, cuDNN, TensorRT, 多媒体组件和开发工具。Jetson 上不要只记录 Ubuntu 版本, 还要记录 JetPack 或 L4T 信息。

cat /etc/nv_tegra_release

tegrastats

tegrastats 是 Jetson 上观察资源的核心工具, 可显示 CPU/GPU/内存/温度/功耗等信息。课程中用于记录 Qwen 推理时的资源变化。

tegrastats

保存日志:

tegrastats --interval 1000 | tee ~/edge-ai-lab/logs/tegrastats-qwen.txt

nvpmodeljetson_clocks

Jetson 的性能受功耗模式和频率策略影响。实验报告必须记录当前功耗模式。

sudo nvpmodel -q
sudo jetson_clocks --show

不要在没有说明的情况下切换功耗模式, 否则不同实验之间不可比。

Ubuntu Server 环境检查

最小检查命令

uname -a
lsb_release -a 2>/dev/null || cat /etc/os-release
python3 --version
git --version
cmake --version
nvidia-smi

GPU 进程和显存

nvidia-smi --query-gpu=name,driver_version,memory.total,memory.used,temperature.gpu,power.draw --format=csv
nvidia-smi --query-compute-apps=pid,process_name,used_memory --format=csv

周期观察

watch -n 1 nvidia-smi

如果不能使用 watch, 可以用:

while true; do
date
nvidia-smi --query-gpu=memory.used,utilization.gpu,temperature.gpu,power.draw --format=csv
sleep 1
done

Jetson 环境检查

最小检查命令

cat /etc/nv_tegra_release
uname -a
free -h
df -h
python3 --version
git --version
cmake --version

Jetson 资源和功耗

tegrastats
sudo nvpmodel -q
sudo jetson_clocks --show

保存一次 Jetson 快照

{
date
cat /etc/nv_tegra_release
uname -a
free -h
df -h
python3 --version
git --version
cmake --version
sudo nvpmodel -q
sudo jetson_clocks --show
} | tee ~/edge-ai-lab/results/jetson-env.txt
警告

Jetson 上的内存常与 GPU 共享。不要用服务器独立显存的思维直接判断 Jetson 是否“显存足够”。要同时看系统内存, swap, 温度和功耗。

llama.cpp 构建与运行

获取源码

mkdir -p ~/edge-ai-lab/repos
cd ~/edge-ai-lab/repos
git clone https://github.com/ggml-org/llama.cpp.git
cd llama.cpp
git rev-parse --short HEAD

保存 commit:

git rev-parse HEAD | tee ~/edge-ai-lab/results/llama-cpp-commit.txt

CUDA 构建

cmake -B build -DGGML_CUDA=ON
cmake --build build --config Release -j

检查二进制:

./build/bin/llama-cli --help | head
./build/bin/llama-server --help | head

运行 Qwen GGUF

./build/bin/llama-cli \
-m ~/edge-ai-lab/models/qwen/qwen2.5-1.5b-instruct-q4_k_m.gguf \
-p "请用三点说明端侧模型部署的主要约束。" \
-n 128 \
--ctx-size 2048 \
-ngl 99

判断 GPU offload:

  • 构建日志中能看到 CUDA backend。
  • 运行日志中出现 GPU/CUDA 相关 backend 信息。
  • nvidia-smitegrastats 中能观察到资源变化。
  • 改变 -ngl 0-ngl 99 后性能和资源路径有差异。

本地服务检查

启动 OpenAI-compatible 服务:

./build/bin/llama-server \
-m ~/edge-ai-lab/models/qwen/qwen2.5-1.5b-instruct-q4_k_m.gguf \
--host 127.0.0.1 \
--port 8080 \
--ctx-size 2048 \
-ngl 99

使用 curl 验证:

curl -s http://127.0.0.1:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "local-qwen",
"messages": [
{"role": "user", "content": "用一句话解释什么是端侧推理。"}
],
"max_tokens": 64
}'

如果 API 调用失败, 按顺序检查:

  1. 服务是否仍在运行。
  2. 端口是否正确。
  3. 模型是否加载成功。
  4. JSON 是否合法。
  5. 日志中是否有 OOM, unsupported backend 或超时。

常见问题定位

现象可能原因检查方法
nvidia-smi 不存在未安装驱动, 非 NVIDIA GPU 环境, Jetson 上工具不同服务器查 driver, Jetson 查 /etc/nv_tegra_release
构建成功但 GPU 没负载未启用 CUDA 后端或 -ngl 太低看 CMake 参数, 运行日志, 改 -ngl
模型加载 OOM模型过大, ctx 太大, 其他进程占用降低模型格式/ctx, 清理进程, 记录峰值
CLI 能跑, API 失败服务参数, 端口, JSON, chat template 问题看 server 日志和 curl 响应
Jetson 跑一段时间变慢温度或功耗限制记录 tegrastats, nvpmodel, 散热条件
结果不可复现未记录版本和参数保存 env, commit, prompt, 模型文件名

配套实作

实作 1: Ubuntu 环境报告

对应章节: Ubuntu Server 与 NVIDIA GPU 环境

产物:

~/edge-ai-lab/results/ubuntu-env.txt
~/edge-ai-lab/results/llama-cpp-commit.txt
~/edge-ai-lab/logs/qwen-baseline.log

验收:

  • 能看到 GPU 型号和 driver。
  • 能看到 CMake/Git/Python 版本。
  • 能看到 llama.cpp commit。
  • 能跑一次 Qwen CLI 推理。

实作 2: Jetson 环境报告

对应章节: Jetson 环境与 Qwen 迁移

产物:

~/edge-ai-lab/results/jetson-env.txt
~/edge-ai-lab/logs/tegrastats-qwen.txt
~/edge-ai-lab/logs/qwen-jetson.log

验收:

  • 能看到 Jetson Linux/L4T 信息。
  • 能看到功耗模式。
  • 能保存 tegrastats 日志。
  • 能说明 Jetson 与 Ubuntu Server 的资源差异。

实作 3: CPU/GPU offload 对比

对应章节: 推理加速实验

固定模型和 prompt, 分别运行:

-ngl 0
-ngl 99

结果模板:

设备ngl峰值显存/内存首 tokentokens/s资源观察备注
Ubuntu GPU0待填待填待填待填待填
Ubuntu GPU99待填待填待填待填待填
Jetson0待填待填待填待填待填
Jetson99待填待填待填待填待填

验收结果

产物验收标准
环境检查日志包含系统, Python, Git, CMake, GPU/Jetson 信息
构建记录包含 llama.cpp commit 和 CMake 参数
运行日志包含模型路径, prompt, ctx, ngl 和性能统计
资源监控Ubuntu 有 nvidia-smi, Jetson 有 tegrastats
问题定位说明能把失败归类到驱动, CUDA, 构建, 运行参数, 模型或服务层

常见问题

CUDA toolkit 和 driver 是一回事吗?

不是。Driver 让系统识别 GPU 并提供运行支持; toolkit 提供编译器和开发文件。运行已有 GPU 程序未必需要完整 toolkit, 但从源码编译 CUDA 后端通常需要。

为什么 nvidia-smi 正常, 但 llama.cpp 没用 GPU?

常见原因是构建时没有启用 -DGGML_CUDA=ON, 运行时没有设置足够的 -ngl, 或实际使用的是另一个未启用 CUDA 的二进制。

Jetson 上为什么不用 nvidia-smi?

Jetson 的监控方式和桌面/服务器 NVIDIA GPU 不完全相同。课程主要使用 tegrastats, nvpmodel 和 Jetson 系统信息来记录资源状态。

是否建议一开始就用 Docker?

如果班级环境差异大, Docker 有帮助。但初学阶段建议先理解宿主机 driver, CUDA 和本地构建关系。否则容器失败时很难定位是宿主机, 容器权限还是镜像问题。

为什么要记录 commit?

llama.cpp, Qwen 文档和低比特格式支持都在持续更新。没有 commit 和版本信息, 实验结果很难复现或比较。

可以把模型文件放进 Git 仓库吗?

不可以。模型权重, 构建产物, 下载仓库和实验日志通常都应放在本地实验目录或外部存储, 不进入课程源码仓库。

参考资料