无 Docker、禁开端口的租用 GPU:大模型推理平台落地全流程
租来的 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-len | max-num-seqs | 部署建议 |
|---|---|---|---|---|
| 4090 / A10 | 24G | 8192 | 8~16 | 单卡跑 7B 量化模型 |
| A100 | 40G | 16384 | 32 | 可开中等并发 |
| H100 | 80G | 32768 | 64 | 多实例分卡部署 |
核心结论: 显存利用率给到 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、不开端口,照样能把大模型推理服务稳稳跑在租来的卡上。
更多推荐



所有评论(0)