Sealessland logo Sealessland
Tutorial

Jetson上用vLLM推理不同模型

在 Jetson 上用 vLLM 推理在线模型和本地模型,并按 1TB 盘上的目录结构组织模型文件。

JetsonDockervLLM

Jetson上用vLLM推理不同模型

下面统一使用 vllm:jetson-orin

模型目录

Jetson 系统盘容量通常比较有限,模型、缓存和容器层应尽量放在外部大容量存储上。

我这里统一放到 1TB 盘:

sudo mkdir -p /media/jetson/disk1TB/huggingface
sudo chown -R jetson:jetson /media/jetson/disk1TB/huggingface

后文默认使用以下目录:

/media/jetson/disk1TB/huggingface
/media/jetson/disk1TB/huggingface/local-models

容器里统一挂成:

-v /media/jetson/disk1TB/huggingface:/root/.cache/huggingface

下面所有例子都默认模型和缓存放在 1TB 盘,服务监听 8000 端口。

推荐的目录结构如下:

/media/jetson/disk1TB/huggingface/
├── hub/
│   └── ...
└── local-models/
    ├── Qwen2.5-0.5B-Instruct/
    │   ├── config.json
    │   ├── tokenizer.json
    │   └── model.safetensors
    ├── Qwen2.5-1.5B-Instruct/
    │   └── ...
    └── qwen3.5-9b-w4a16/
        └── ...

这个布局对应两类数据:

  • hub/ 用于 Hugging Face 缓存。
  • local-models/ 用于保存已经下载完成、准备直接挂载给 vLLM 的本地模型目录。

先看一条完整命令

sudo docker run -d --name vllm-qwen-online --restart unless-stopped \
  --runtime=nvidia --network host \
  -e HF_ENDPOINT=https://hf-mirror.com \
  -e HF_HOME=/root/.cache/huggingface \
  -e HF_HUB_DISABLE_XET=1 \
  -v /media/jetson/disk1TB/huggingface:/root/.cache/huggingface \
  vllm:jetson-orin \
  vllm serve Qwen/Qwen2.5-0.5B-Instruct \
  --served-model-name Qwen2.5-0.5B-Instruct \
  --host 0.0.0.0 \
  --port 8000 \
  --gpu-memory-utilization 0.7

这条命令可以拆成三段:

  • sudo docker run ... vllm:jetson-orin 负责启动容器。
  • vllm serve Qwen/Qwen2.5-0.5B-Instruct 指定需要加载的模型。
  • --served-model-name ... --host ... --port ... 控制对外模型名、监听地址和显存占用。

Docker 参数怎么读

通常需要调整的是 --name、模型路径、端口、对外模型名和显存占用。

sudo docker run

  • 启动一个新容器。

-d

  • 后台运行。不使用该参数时,日志会直接输出到当前终端。

--name vllm-qwen-online

  • 为容器指定名称,后续查看日志、停止服务和删除容器时都会用到。

--restart unless-stopped

  • 宿主机重启后自动恢复;如果手动执行 docker stop,则不会自动重新启动。

--runtime=nvidia

  • 使容器使用 NVIDIA runtime。Jetson 上需要这一项才能访问 GPU。

--network host

  • 直接使用宿主机网络。服务监听 8000 端口后,宿主机可以直接通过 127.0.0.1:8000 访问。

-e HF_ENDPOINT=https://hf-mirror.com

  • 指定 Hugging Face 下载镜像。

-e HF_HOME=/root/.cache/huggingface

  • 指定容器内的 Hugging Face 缓存根目录。

-e HF_HUB_DISABLE_XET=1

  • 避免部分 Xet 大文件下载超时问题。

-v /media/jetson/disk1TB/huggingface:/root/.cache/huggingface

  • 将宿主机 1TB 盘上的目录挂载到容器内。模型与缓存会保留在宿主机上,不会因容器删除而丢失。

vllm:jetson-orin

  • 指定运行所使用的镜像。

在线拉模型

模型尚未保存到本地时,可以直接在线拉取。下面几条命令里,主要变化的是容器名、模型名和显存占用。

对于长期使用的模型,更推荐先在个人电脑完成下载,再复制到 Jetson 的 /media/jetson/disk1TB/huggingface/local-models/。这样通常比直接在 Jetson 上在线下载更快,也更容易排查问题。

0.5B

sudo docker run -d --name vllm-qwen05b --restart unless-stopped \
  --runtime=nvidia --network host \
  -e HF_ENDPOINT=https://hf-mirror.com \
  -e HF_HOME=/root/.cache/huggingface \
  -e HF_HUB_DISABLE_XET=1 \
  -v /media/jetson/disk1TB/huggingface:/root/.cache/huggingface \
  vllm:jetson-orin \
  vllm serve Qwen/Qwen2.5-0.5B-Instruct \
  --served-model-name Qwen2.5-0.5B-Instruct \
  --host 0.0.0.0 \
  --port 8000 \
  --gpu-memory-utilization 0.7

适合用于验证镜像、下载链路和接口是否正常。

1.5B

sudo docker run -d --name vllm-qwen15b --restart unless-stopped \
  --runtime=nvidia --network host \
  -e HF_ENDPOINT=https://hf-mirror.com \
  -e HF_HOME=/root/.cache/huggingface \
  -e HF_HUB_DISABLE_XET=1 \
  -v /media/jetson/disk1TB/huggingface:/root/.cache/huggingface \
  vllm:jetson-orin \
  vllm serve Qwen/Qwen2.5-1.5B-Instruct \
  --served-model-name Qwen2.5-1.5B-Instruct \
  --host 0.0.0.0 \
  --port 8000 \
  --gpu-memory-utilization 0.7

相较于 0.5B,这个规模更接近正式使用场景,同时资源压力仍然相对可控。

量化 9B

sudo docker run -d --name vllm-qwen-quant --restart unless-stopped \
  --runtime=nvidia --network host \
  -e HF_ENDPOINT=https://hf-mirror.com \
  -e HF_HOME=/root/.cache/huggingface \
  -e HF_HUB_DISABLE_XET=1 \
  -v /media/jetson/disk1TB/huggingface:/root/.cache/huggingface \
  vllm:jetson-orin \
  vllm serve Kbenkhaled/Qwen3.5-9B-quantized.w4a16 \
  --served-model-name Qwen3.5-9B-quantized \
  --host 0.0.0.0 \
  --port 8000 \
  --gpu-memory-utilization 0.8

量化模型更容易在下载和初始化阶段出现问题,建议优先查看日志,而不是仅依赖 docker ps 的状态。

改别的在线模型

在线模型通常只需要调整以下两处:

vllm serve <repo_id>
--served-model-name <接口对外暴露的模型>

例如:

vllm serve Qwen/Qwen2.5-3B-Instruct
--served-model-name Qwen2.5-3B-Instruct
vllm serve Qwen/Qwen2.5-7B-Instruct
--served-model-name Qwen2.5-7B-Instruct

平时真正会改哪些参数

切换模型时,通常不会调整 HF 相关固定项。需要频繁修改的是模型名、容器名、端口、显存占用和本地模型路径。

每次换模型基本都会动这些:

  • --name 容器名。建议不同模型使用不同容器名,便于查看日志和管理服务。
  • vllm serve <repo_id>vllm serve /models/... 直接决定加载哪个模型。
  • --served-model-name API 对外暴露的模型名。
  • --port 在同一台设备上部署多个服务时经常需要调整。
  • --gpu-memory-utilization 模型规模变化后,通常需要随之调整。
  • -v /media/jetson/disk1TB/huggingface/local-models/...:/models/...:ro 本地模型目录发生变化时,需要同步修改。

这几项在这台 Jetson 上通常是固定的:

--runtime=nvidia
--network host
-e HF_ENDPOINT=https://hf-mirror.com
-e HF_HOME=/root/.cache/huggingface
-e HF_HUB_DISABLE_XET=1
-v /media/jetson/disk1TB/huggingface:/root/.cache/huggingface
  • --runtime=nvidia 启用 GPU。
  • --network host 使用宿主机网络。
  • HF_ENDPOINT 下载使用镜像站。
  • HF_HOME 缓存根目录固定为容器内的 /root/.cache/huggingface
  • HF_HUB_DISABLE_XET=1 用于处理大文件下载场景。
  • 第一条 -v 将缓存固定保存在 1TB 盘上。

本地模型

模型已经放到 1TB 盘时,可以直接挂载对应目录。

这种方式通常比在 Jetson 上直接在线下载更高效。对于较大的模型,建议先在个人电脑下载完成,再通过局域网复制过去。

/media/jetson/disk1TB/huggingface/local-models/Qwen2.5-0.5B-Instruct

本地模型目录与挂载关系

建议保持“宿主机目录”和“容器内目录”一一对应,便于后续切换模型:

宿主机目录
/media/jetson/disk1TB/huggingface/local-models/Qwen2.5-0.5B-Instruct

容器内目录
/models/Qwen2.5-0.5B-Instruct

因此,docker run 中的挂载和 vllm serve 应当成对出现:

-v /media/jetson/disk1TB/huggingface/local-models/Qwen2.5-0.5B-Instruct:/models/Qwen2.5-0.5B-Instruct:ro
vllm serve /models/Qwen2.5-0.5B-Instruct

这里末尾的 :ro 表示只读挂载,也就是容器只能读取这个目录,不能在里面写入文件。对于本地模型目录,这样更安全,也更符合使用场景。

启动:

sudo docker run -d --name vllm-qwen-local --restart unless-stopped \
  --runtime=nvidia --network host \
  -e HF_HOME=/root/.cache/huggingface \
  -v /media/jetson/disk1TB/huggingface:/root/.cache/huggingface \
  -v /media/jetson/disk1TB/huggingface/local-models/Qwen2.5-0.5B-Instruct:/models/Qwen2.5-0.5B-Instruct:ro \
  vllm:jetson-orin \
  vllm serve /models/Qwen2.5-0.5B-Instruct \
  --served-model-name Qwen2.5-0.5B-Instruct \
  --host 0.0.0.0 \
  --port 8000 \
  --gpu-memory-utilization 0.7

本地模型推理时,第二个 -vvllm serve 必须保持一致。挂载路径与模型路径不对应时,服务通常无法完成初始化。

不同本地目录的示例

如果本地模型保存在不同子目录中,只需要同步修改挂载路径和 vllm serve 的目标路径。

目录一:Qwen2.5-0.5B-Instruct

sudo docker run -d --name vllm-qwen05b-local --restart unless-stopped \
  --runtime=nvidia --network host \
  -e HF_HOME=/root/.cache/huggingface \
  -v /media/jetson/disk1TB/huggingface:/root/.cache/huggingface \
  -v /media/jetson/disk1TB/huggingface/local-models/Qwen2.5-0.5B-Instruct:/models/Qwen2.5-0.5B-Instruct:ro \
  vllm:jetson-orin \
  vllm serve /models/Qwen2.5-0.5B-Instruct \
  --served-model-name Qwen2.5-0.5B-Instruct \
  --host 0.0.0.0 \
  --port 8000 \
  --gpu-memory-utilization 0.7

目录二:Qwen2.5-1.5B-Instruct

sudo docker run -d --name vllm-qwen15b-local --restart unless-stopped \
  --runtime=nvidia --network host \
  -e HF_HOME=/root/.cache/huggingface \
  -v /media/jetson/disk1TB/huggingface:/root/.cache/huggingface \
  -v /media/jetson/disk1TB/huggingface/local-models/Qwen2.5-1.5B-Instruct:/models/Qwen2.5-1.5B-Instruct:ro \
  vllm:jetson-orin \
  vllm serve /models/Qwen2.5-1.5B-Instruct \
  --served-model-name Qwen2.5-1.5B-Instruct \
  --host 0.0.0.0 \
  --port 8001 \
  --gpu-memory-utilization 0.7

目录三:qwen3.5-9b-w4a16

sudo docker run -d --name vllm-qwen35-quant-local --restart unless-stopped \
  --runtime=nvidia --network host \
  -e HF_HOME=/root/.cache/huggingface \
  -v /media/jetson/disk1TB/huggingface:/root/.cache/huggingface \
  -v /media/jetson/disk1TB/huggingface/local-models/qwen3.5-9b-w4a16:/models/qwen3.5-9b-w4a16:ro \
  vllm:jetson-orin \
  vllm serve /models/qwen3.5-9b-w4a16 \
  --served-model-name Qwen3.5-9B-quantized \
  --host 0.0.0.0 \
  --port 8002 \
  --gpu-memory-utilization 0.8

切换本地模型时需要同步修改的部分

-v /media/jetson/disk1TB/huggingface/local-models/otherModel-1b:/models/otherModel-1b:ro
vllm serve /models/otherModel-1b

本地目录最好至少有这些文件:

  • config.json
  • tokenizer.json
  • tokenizer_config.json
  • generation_config.json
  • model.safetensors

目录不完整时,容器进程可能仍然存在,但接口服务通常不会成功启动。

怎么判断服务到底起没起来

docker ps 里显示 Up,不等于接口已经能用。

容器显示 Up 只表示主进程仍在运行,并不等于 8000 端口已经开始监听。

先查模型列表:

curl http://127.0.0.1:8000/v1/models

然后发送一条 chat/completions 请求:

curl http://127.0.0.1:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "Qwen2.5-0.5B-Instruct",
    "messages": [
      {"role": "system", "content": "You are a concise assistant."},
      {"role": "user", "content": "你好,请用一句话介绍你自己。"}
    ],
    "temperature": 0.7,
    "max_tokens": 128
  }'

如果 curl 返回连接拒绝,建议先查看日志:

sudo docker logs -f vllm-qwen-local

再看端口:

ss -ltnp | grep :8000

如果需要调整接口中的模型名,应同步修改 --served-model-name 和请求体中的 model 字段。

直接测接口

先看服务里暴露了哪些模型:

curl http://127.0.0.1:8000/v1/models

再发一条最常用的 chat/completions

curl http://127.0.0.1:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "Qwen2.5-0.5B-Instruct",
    "messages": [
      {"role": "system", "content": "You are a concise assistant."},
      {"role": "user", "content": "你好,请用一句话介绍你自己。"}
    ],
    "temperature": 0.7,
    "max_tokens": 128
  }'

如果接口返回模型不存在,优先检查 --served-model-name 是否与请求体中的 model 字段一致。

停止和删除

停止:

sudo docker stop vllm-qwen-local

删除:

sudo docker rm vllm-qwen-local

切换到别的模型

在线模型与本地模型的调整方式不同:

  • 在线时改 vllm serve <repo_id>
  • 本地时同时修改 1TB 盘里的模型目录、挂载路径和 vllm serve /models/...