租来的 GPU 机器,往往没有 Docker 守护进程、安全组只放行 22 端口、环境随时可能被回收。想在上面跑一套大模型推理服务,第一反应是打镜像、开端口、挂负载均衡,结果三条路全被堵死:dockerd 起不来,安全组不给开 8000,重装一遍又要半小时。

常规的容器化部署在这里根本走不通,而「conda 全局装 + 开公网端口」的老办法又会撞上 sudo 权限缺失和防火墙拦截。真正需要解决的是三个问题:依赖装在哪、服务怎么被访问、挂了谁来拉起来。

本文分享一套在裸机约束下落地大模型推理平台的方案:用户态安装 + SSH 隧道暴露接口 + systemd 常驻自愈,可直接落地。

一、租卡现场的约束盘点:三个卡点先摸清

先把限制摸清楚,才知道哪些路不能走:

  • 装不了 Docker:多数租卡平台禁止特权模式,dockerd 缺少 cgroup 挂载权限,拉镜像还会被限速。
  • 打不开公网端口:安全组通常只放行 22,改防火墙需要工单审批,等不起。
  • 环境会被回收:机器可能随时被重置,装在系统目录的依赖和手工 nohup 起的进程全会丢。
卡点常规做法这里的替代方案
装不了 Docker写 Dockerfile 打镜像用户态安装到家目录
打不开公网端口安全组放行服务端口SSH 本地端口转发
环境会被回收容器自动重启策略systemd Restart=always

核心结论: 三个卡点各自都有绕行手段,但必须同时成立,缺一个链路就断。

在这里插入图片描述

二、绕开容器:把整套依赖装进用户态目录

没有 root 权限也能装齐 CUDA 相关依赖,关键在于全部落在家目录:

  • Miniconda 用户态安装:安装器加 -b -p $HOME/miniconda3,不碰 /usr,卸载即删目录。
  • 官方 manylinux wheel:vLLM 这类项目发布的 wheel 自带 CUDA runtime,只需驱动版本匹配,无需系统级 apt。
  • PATH 只对自己生效:source etc/profile.d/conda.sh 后激活环境,不影响同机其他用户。

这段脚本在无 sudo 的裸机上创建独立 Python 环境并装好推理框架,适配 Ubuntu 22.04 及同系发行版:

# 用户态安装 Miniconda 并创建推理环境
wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh -b -p $HOME/miniconda3
source $HOME/miniconda3/etc/profile.d/conda.sh
conda create -n llm python=3.11 -y && conda activate llm
pip install vllm -i https://pypi.tuna.tsinghua.edu.cn/simple

强依赖全部落在家目录 → 环境被重置后 5 分钟可重建。

三、单条命令拉起推理服务与兼容接口

依赖就绪后,一条命令即可暴露 OpenAI 兼容接口:

vllm serve Qwen/Qwen2.5-7B-Instruct \
  --host 127.0.0.1 --port 8000 \
  --gpu-memory-utilization 0.90 \
  --max-model-len 8192 \
  --max-num-seqs 16 \
  --served-model-name qwen2.5-7b

只监听 127.0.0.1 → 公网扫不到,先起服务再谈访问。

参数作用取值建议
--host监听地址固定 127.0.0.1
--gpu-memory-utilization显存占用上限0.85~0.92
--max-model-len单请求上下文长度按业务输入裁剪
--max-num-seqs并发序列数显存越大越高
--served-model-name对外模型名便于客户端切换

在这里插入图片描述

四、不开公网端口:用 SSH 隧道搬回本地

公网端口打不开,就让 SSH 帮你把服务搬到本地:

  • 本地端口转发:-N -L 8000:127.0.0.1:8000 把远端回环地址映射到本机,流量走 22 端口加密。
  • 多跳跳板场景:套一层 -J user@jump 即可穿透内网机器,无需在跳板上开任何端口。
  • 团队共享:每人各自建隧道,服务端零改动,也不用担心公网被扫。

这段命令在本地机器执行,随后用 curl 验证接口是否可达:

# 本地终端:把远端 127.0.0.1:8000 映射到本机 8000
ssh -N -L 8000:127.0.0.1:8000 -i ~/.ssh/gpu_ed25519 ubuntu@1.2.3.4 &
# 另开一个终端验证
curl -s http://127.0.0.1:8000/v1/models

核心结论: 隧道断了重连即可,服务端始终只暴露一个 22 端口,安全面最小。

五、显存与并发取舍:按卡型定参数

显存是租卡上最贵的资源,参数必须按卡型算:

  • 先留权重再算 KV Cache:gpu-memory-utilization 扣掉模型权重后剩余部分才是 KV Cache 空间。
  • 上下文比并发更吃显存:max-model-len 翻倍,KV Cache 近似翻倍,优先砍长度而非砍并发。
  • OOM 就降 utilization:报 CUDA out of memory 时先降到 0.85,再调小 max-num-seqs。
卡型显存max-model-lenmax-num-seqs部署建议
4090 / A1024G81928~16单卡跑 7B 量化模型
A10040G1638432可开中等并发
H10080G3276864多实例分卡部署

核心结论: 显存利用率给到 0.9,长度和并发二者只调一个,避免同时变量导致无法定位 OOM。

六、常驻与自愈:systemd 托管推理服务

机器一重启服务就没了,交给 systemd 托管才能自愈:

  • Restart=always:进程崩溃或机器重启后自动拉起,比 nohup 可靠一个量级。
  • 健康检查:定时 curl /health,连续失败就重启服务,避免端口在但模型卡死。
  • 日志归档:journalctl -u 统一收集,租卡回收前可导出排查。

下面的单元文件把服务写成系统服务,配合一条健康检查命令,适配有 systemd 的裸机环境:

cat > ~/.config/systemd/user/vllm.service <<'EOF'
[Unit]
Description=vLLM inference server
After=network.target
[Service]
ExecStart=%h/miniconda3/envs/llm/bin/vllm serve Qwen/Qwen2.5-7B-Instruct --host 127.0.0.1 --port 8000
Restart=always
RestartSec=10
[Install]
WantedBy=default.target
EOF
systemctl --user daemon-reload && systemctl --user enable --now vllm
# 健康检查:失败则由 Restart=always 兜底
curl -sf http://127.0.0.1:8000/health || systemctl --user restart vllm

进程挂掉 → 10 秒拉起 → 健康检查兜底。

在这里插入图片描述

结语

这套方案的价值在于把「容器 + 公网端口」的默认假设换成了三个更朴素的原语:依赖装在家目录、访问走 SSH 隧道、进程交给 systemd。整条链路不依赖任何特权权限,也不需要向平台申请额外端口,在绝大多数租卡环境都能原样复用;服务被回收后,重跑安装脚本加一条 systemctl 命令即可在几分钟内恢复。

更关键的是,它把不确定性变成了可运维的确定项:端口面收敛到 22、显存参数按卡型查表、崩溃有自愈闭环。没有 Docker、不开端口,照样能把大模型推理服务稳稳跑在租来的卡上。

Logo

更多推荐