news 2026/10/8 12:00:26

Ubuntu Server 搭建远程 AI 工作站实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Ubuntu Server 搭建远程 AI 工作站实战指南

1. 为什么非得用 Ubuntu Server 搭建远程 AI 工作站?——不是图新鲜,是算过账的

你可能已经看过太多“Ubuntu 桌面版 + VS Code Remote SSH”的教程,点开就是图形界面、拖拽文件、右键运行——看起来很美。但如果你真把一台 16GB 内存、RTX 4070 的小主机(比如 Intel N100 迷你 PC 或 AMD Ryzen 5 7640HS 的工控盒子)长期当 AI 开发机用,不出三天就会发现:桌面环境在后台偷偷吃掉 2.3GB 内存、GNOME Shell 占用 12% CPU、Docker Desktop 启动要等 47 秒、连个nvidia-smi都要等半秒响应。这不是体验问题,是资源错配。

我去年在实验室部署了 7 台同配置的 Ubuntu Server 小主机,全部用于支撑学生做 LLM 微调、RAG 流程开发和本地模型推理服务。没有一个装桌面,全靠纯命令行 + VS Code Remote SSH + JupyterLab Web 界面。半年下来,平均单机日均稳定运行时长 22.8 小时,GPU 利用率峰值达 94%,而系统自身开销始终压在 380MB 内存 + <1.2% CPU。这不是玄学,是 Ubuntu Server 的设计哲学决定的:它不预装任何与“交互”强相关的进程,所有资源都留给你的transformers加载、vLLM推理或Ollama拉取模型用。

更关键的是安全水位线。Ubuntu Server 默认禁用 GUI、禁用snapd(除非你明确需要)、默认只开 SSH(且可精细控制端口/用户/密钥),而桌面版默认启用avahi-daemon(mDNS 广播)、whoopsie(错误上报)、ubuntu-report(遥测)、fwupd(固件更新服务)——这些服务加起来会暴露至少 5 个非必要监听端口,其中 2 个(5353/udp、5355/udp)在内网中极易被扫描利用。我们实测过:同一台机器,Server 版本ss -tuln | wc -l输出为 11,桌面版则为 28。多出的 17 个监听项里,有 9 个与 AI 开发完全无关,却构成潜在攻击面。

所以,“从零开始”不是教你怎么点鼠标,而是带你重建一套以 AI 工作为中心的最小可行操作系统栈:它必须满足三个硬约束——

  • 内存可控:整机 8GB 内存下,系统基础占用 ≤450MB;
  • GPU 可见:NVIDIA/AMD 显卡驱动能被torch和vLLM正确识别,CUDA/cuDNN 版本严格对齐;
  • 远程可信:SSH 登录后,能直接cd ~/ai-workspace && make run-server启动 RAG 服务,无需二次 sudo、无需图形切换、无需环境变量重载。

这背后是一整套与桌面发行版截然不同的运维逻辑:你不再“使用系统”,而是“编排系统”。接下来每一节,都是我在 7 台机器上反复验证过的、不可跳过的硬核步骤。

2. 网络层奠基:netplan 配置不是写 YAML,是定义 AI 流量的高速公路

很多人卡在第一步:Ubuntu Server 安装完,ip a看不到 IP,或者ssh user@192.168.1.100死活连不上。他们翻遍论坛,最后发现是 netplan 配置错了。但问题从来不在 YAML 语法,而在没想清楚——你的 AI 工作站到底要走哪条路?

我见过最典型的错误配置是这样写的:

network: version: 2 renderer: networkd ethernets: enp0s31f6: dhcp4: true

看着没错,但实际后果是:每次重启,IP 地址随机分配,VS Code Remote SSH 连接字符串要手动改;内网其他设备(比如你的笔记本)无法通过固定域名访问这台工作站;更致命的是,当你用docker run -p 8000:8000启动 vLLM 服务时,外部根本无法访问http://192.168.1.x:8000——因为 DHCP 分配的地址可能被路由器回收,也可能与其他设备冲突。

真正的 netplan 配置,必须回答三个问题:

  • 定位问题:这台机器在局域网中的唯一身份是什么?(不是“某台 Ubuntu”,而是ai-dev-03)
  • 路径问题:AI 流量(HTTP API、SSH、JupyterLab WebSocket)必须走哪条物理链路?(有线还是无线?是否需双网卡冗余?)
  • 边界问题:哪些端口必须对外暴露?哪些必须严格限制在内网?(比如22可以开放,但6379Redis 绝不能暴露)

我的标准配置(适配绝大多数千兆有线环境)如下:

# /etc/netplan/01-network-manager-all.yaml network: version: 2 renderer: networkd ethernets: enp0s31f6: # 请先用 ip link show 确认你的网卡名 dhcp4: false addresses: [192.168.1.103/24] # 固定 IP,比 DHCP 可靠 10 倍 routes: - to: default via: 192.168.1.1 # 路由器网关 nameservers: addresses: [114.114.114.114, 223.5.5.5] # 国内 DNS,快且稳 # 关键:禁止该网卡参与 IPv6 自动配置(避免干扰) ipv6-address-generation: eui64 accept-ra: false

提示:enp0s31f6是 Intel 主板常见网卡名,AMD 平台可能是enp3s0或eno1。执行ip link show | grep "state UP"快速定位活跃网卡。别猜,实测为准。

执行生效只需两步:

sudo netplan apply # 然后立刻验证:ping 通网关、能解析域名、能 curl 外网 ping -c 3 192.168.1.1 && nslookup google.com && curl -I https://httpbin.org

但真正考验经验的是——什么时候不该用 netplan?
当你遇到以下任一场景,请立即停手:

  • 你的小主机插着 USB 3.0 网卡(如 AX88179 芯片),ip link显示usb0而非enp*;
  • 你用的是群晖 NAS 的 Docker 容器跑 Ubuntu Server(此时网络由群晖桥接管理);
  • 你所在企业内网强制使用 802.1X 认证(需wpa_supplicant配合)。

这些情况 netplan 无能为力,必须切到systemd-networkd或NetworkManager手动接管。我建议:首次部署务必用原生有线网卡+固定 IP,把网络这个地基打牢,再谈 AI。

3. 远程接入的生死线:SSH 不是登录,是构建可信通道的精密工程

很多人以为 SSH 就是输密码登录。但在 AI 工作站场景下,SSH 是整个工作流的“脊椎”——VS Code Remote SSH 依赖它传输文件、转发端口、启动进程;JupyterLab 的--ip=0.0.0.0依赖它做端口映射;甚至git push到内网 Git 服务器也靠它鉴权。一旦 SSH 出问题,整个 AI 开发链就瘫痪。

我统计过实验室 7 台机器的 SSH 故障类型,排名前三的是:

  1. 密钥权限错误(占 42%):~/.ssh/id_rsa权限为 644,OpenSSH 拒绝加载;
  2. sshd_config 配置冲突(31%):PasswordAuthentication yes与PubkeyAuthentication yes同时开启,导致某些客户端(如 MobaXterm)行为异常;
  3. SELinux/AppArmor 干预(18%):Ubuntu Server 默认启用 AppArmor,某些自定义路径的AuthorizedKeysCommand会被拦截。

所以,我们不装 SSH,我们“锻造”SSH。

3.1 密钥生成:不是ssh-keygen -t rsa,而是ssh-keygen -t ed25519 -C "ai-dev@yourname"

RSA 已过时。Ed25519 是现代 SSH 的黄金标准:密钥更短(32 字节 vs RSA 4096 的 512 字节)、签名更快(实测快 3.2 倍)、抗量子计算能力更强。生成命令必须带-C参数(注释),这是后续排查的唯一线索:

ssh-keygen -t ed25519 -C "ai-dev@zhangsan" -f ~/.ssh/id_ed25519_ai # 生成后立即设置权限 chmod 600 ~/.ssh/id_ed25519_ai chmod 644 ~/.ssh/id_ed25519_ai.pub

3.2 服务端加固:编辑/etc/ssh/sshd_config的 5 个关键行

不要全局搜索替换,逐行确认:

配置项推荐值为什么
Port 2222改为2222避开默认端口扫描,实测使暴力破解尝试下降 92%
PermitRootLogin nonoroot 直接登录是最大风险点,必须禁用
PubkeyAuthentication yesyes唯一允许的认证方式,密码登录彻底关闭
PasswordAuthentication nono与上一行形成硬性互斥,杜绝弱口令漏洞
AllowUsers zhangsanzhangsan明确指定可登录用户,拒绝所有其他账户

改完后重启服务:

sudo systemctl restart sshd # 立即验证:新终端窗口执行 ssh -p 2222 -i ~/.ssh/id_ed25519_ai zhangsan@192.168.1.103

注意:-p 2222是必须的!很多新手忘了改端口,还在用ssh user@ip默认连 22 端口,自然失败。

3.3 客户端免密登录:VS Code Remote SSH 的终极配置

VS Code Remote SSH 插件本质是调用本地ssh命令。所以你要在本地~/.ssh/config中写死连接参数:

# ~/.ssh/config Host ai-dev HostName 192.168.1.103 User zhangsan Port 2222 IdentityFile ~/.ssh/id_ed25519_ai ForwardAgent yes # 允许代理转发,方便 git clone 内网仓库 ServerAliveInterval 60 # 每60秒发心跳,防超时断开

然后在 VS Code 中按Ctrl+Shift+P→ 输入Remote-SSH: Connect to Host...→ 选择ai-dev。它会自动读取 config 文件,无需再输密码、端口、密钥路径。

这才是真正的“远程 AI 工作站”入口:一次配置,永久可用。下次换电脑,只要同步~/.ssh/config和私钥文件,30 秒内恢复全部开发环境。

4. AI 核心栈落地:DeepSeek Harness 不是安装包,是可编排的推理引擎

现在网络通了、SSH 稳了,终于可以谈 AI。但注意:DeepSeek Harness 不是pip install deepseek-harness就完事的玩具。它是 DeepSeek 官方推出的、面向生产环境的 LLM 推理框架,核心价值在于——把模型、提示词、工具调用、输出解析封装成可复用、可调试、可监控的“技能(Skill)”。

它的安装逻辑与传统 Python 包完全不同:

  • 不依赖pip全局安装,而是用conda创建隔离环境(避免与系统 Python 冲突);
  • 不直接git clone,而是用官方发布的deepseek-harness-cli工具下载预编译二进制(省去 23 分钟的rust编译);
  • 不手动配置config.yaml,而是用 CLI 交互式生成(防 YAML 缩进错误)。

4.1 环境准备:Conda + CUDA 驱动的精准对齐

先确认你的 GPU 驱动和 CUDA 版本:

nvidia-smi # 查看驱动版本(如 535.129.03) nvcc --version # 查看 CUDA 编译器版本(如 12.2)

DeepSeek Harness 官方要求:CUDA 12.1+,驱动 ≥535。如果驱动太旧,必须升级:

# 添加 NVIDIA 官方源 sudo apt update && sudo apt install -y software-properties-common sudo add-apt-repository -y ppa:graphics-drivers/ppa sudo apt update sudo apt install -y nvidia-driver-535-server sudo reboot

驱动就绪后,用 Miniconda 创建专用环境:

wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh bash Miniconda3-latest-Linux-x86_64.sh -b -p $HOME/miniconda3 $HOME/miniconda3/bin/conda init bash source ~/.bashrc conda create -n deepseek-env python=3.10 -y conda activate deepseek-env

为什么是 Python 3.10?DeepSeek Harness 的 Rust 绑定层(llm-chain)在 3.11 上存在 ABI 兼容问题,3.10 是当前最稳版本。

4.2 Harness CLI 安装:绕过 GitHub 源码编译的捷径

官方提供预编译 CLI(Linux x86_64),直接下载解压即可:

mkdir -p ~/deepseek-harness && cd ~/deepseek-harness wget https://github.com/deepseek-ai/harness/releases/download/v0.3.0/deepseek-harness-linux-x86_64.tar.gz tar -xzf deepseek-harness-linux-x86_64.tar.gz chmod +x deepseek-harness sudo mv deepseek-harness /usr/local/bin/

验证安装:

deepseek-harness --version # 应输出 v0.3.0

4.3 初始化项目:deepseek-harness init生成的不只是文件,是开发契约

在你的工作目录执行:

mkdir ~/ai-workspace && cd ~/ai-workspace deepseek-harness init

它会交互式提问:

  • Project name?→ 输入rag-engine
  • Model to use?→ 选deepseek-r1(官方推荐的 7B RAG 优化版)
  • Backend?→ 选vLLM(比 HuggingFace Transformers 快 4.7 倍)
  • Enable skill debugging?→yes(开发期必开,否则报错不显示堆栈)

生成的目录结构是精心设计的:

rag-engine/ ├── config.yaml # 全局配置:模型路径、端口、日志级别 ├── skills/ # 所有 Skill 存放处(每个 Skill 是独立可测试单元) │ └── file_reader.py # 示例:读取本地 PDF 的 Skill ├── models/ # 模型存放目录(支持 HuggingFace Hub 或本地路径) └── server.py # 启动 HTTP API 服务的入口

最关键的config.yaml,它定义了 AI 工作站的“服务契约”:

model: name: "deepseek-ai/deepseek-r1" backend: "vllm" device: "cuda" # 强制 GPU 推理 server: host: "0.0.0.0" # 允许所有内网设备访问 port: 8000 cors: true # 允许浏览器前端跨域调用 logging: level: "INFO" file: "/var/log/deepseek-harness.log"

注意host: "0.0.0.0"—— 这是让工作站成为“服务提供者”的关键。如果写成127.0.0.1,只有本机能访问,VS Code 的端口转发也失效。

4.4 技能(Skill)实战:部署一个“读取本地文件”的 RAG 基础组件

创建skills/file_reader.py:

from deepseek_harness.skill import Skill import os class FileReaderSkill(Skill): def __init__(self, file_path: str): super().__init__() self.file_path = file_path def execute(self, input_text: str) -> str: try: with open(self.file_path, 'r', encoding='utf-8') as f: content = f.read(2000) # 限制读取长度,防 OOM return f"文件内容摘要:{content[:200]}..." except FileNotFoundError: return f"错误:文件 {self.file_path} 不存在" except PermissionError: return f"错误:无权限读取 {self.file_path}" # 注册技能,供 CLI 调用 file_reader = FileReaderSkill("/home/zhangsan/docs/manual.md")

然后在config.yaml中注册:

skills: - name: "file_reader" path: "skills/file_reader.py" class: "FileReaderSkill" args: { "file_path": "/home/zhangsan/docs/manual.md" }

启动服务:

cd ~/ai-workspace/rag-engine deepseek-harness serve

服务启动后,用curl测试:

curl -X POST http://192.168.1.103:8000/skill/file_reader \ -H "Content-Type: application/json" \ -d '{"input_text": "summary"}'

返回文件内容摘要:# 用户手册...,说明 Skill 已就绪。这就是你的第一个可部署的 AI 组件——它不依赖图形界面,不依赖浏览器,纯 API 驱动,可被任何内网设备调用。

5. 生产就绪:让 AI 工作站 7×24 小时在线的 4 个隐形开关

装完 DeepSeek Harness,很多人就以为大功告成。但真实场景中,AI 工作站不是“能跑就行”,而是“必须一直跑”。我见过太多案例:学生深夜跑微调,早上发现进程没了;RAG 服务下午还正常,晚上就 502;nvidia-smi显示 GPU 0% 利用率,但ps aux | grep vllm找不到进程。

问题不在 AI 框架,而在 Linux 系统级的“隐形开关”没拨对。

5.1 systemd 服务:让deepseek-harness serve成为系统级守护进程

创建服务文件/etc/systemd/system/deepseek-harness.service:

[Unit] Description=DeepSeek Harness AI Server After=network.target [Service] Type=simple User=zhangsan WorkingDirectory=/home/zhangsan/ai-workspace/rag-engine ExecStart=/home/zhangsan/miniconda3/envs/deepseek-env/bin/deepseek-harness serve Restart=always RestartSec=10 Environment="PATH=/home/zhangsan/miniconda3/envs/deepseek-env/bin:/usr/local/bin:/usr/bin:/bin" Environment="CUDA_VISIBLE_DEVICES=0" [Install] WantedBy=multi-user.target

关键点解析:

  • User=zhangsan:必须指定用户,不能用 root(安全红线);
  • Environment="CUDA_VISIBLE_DEVICES=0":显式绑定 GPU,避免多卡时被其他进程抢占;
  • Restart=always:进程崩溃后自动重启,RestartSec=10防止频繁重启(健康检查间隔);
  • Environment="PATH=...":精确指定 conda 环境路径,避免找不到deepseek-harness命令。

启用并启动:

sudo systemctl daemon-reload sudo systemctl enable deepseek-harness.service sudo systemctl start deepseek-harness.service # 查看状态 sudo systemctl status deepseek-harness.service

实测效果:即使kill -9主进程,10 秒内自动拉起,日志无缝续写到/var/log/deepseek-harness.log。

5.2 日志轮转:不配置 logrotate,3 天后磁盘就爆

DeepSeek Harness 默认日志不切割。实测连续运行 48 小时,日志文件达 1.2GB。/var/log分区通常只有 2GB,爆满后 SSH 都无法登录。

创建/etc/logrotate.d/deepseek-harness:

/var/log/deepseek-harness.log { daily missingok rotate 30 compress delaycompress notifempty create 644 zhangsan zhangsan sharedscripts postrotate systemctl kill --signal=SIGHUP deepseek-harness.service > /dev/null 2>&1 || true endscript }

解释:每天轮转,保留 30 天压缩日志,postrotate中向服务发送SIGHUP信号,通知其重新打开日志文件(Harness 支持此信号)。

5.3 GPU 内存泄漏防护:nvidia-smi 不是监控,是故障预警器

vLLM 在长时间运行后可能出现 GPU 内存缓慢增长(每小时 +12MB),72 小时后达 2.1GB,触发 OOM Killer 杀死进程。

解决方案:用cron每 2 小时检查并清理:

# 编辑 crontab crontab -e # 添加一行 0 */2 * * * /usr/bin/nvidia-smi --gpu-reset -i 0 2>/dev/null || true

nvidia-smi --gpu-reset会重置 GPU 状态(不重启驱动),实测可将内存泄漏归零,且不影响正在运行的推理请求(毫秒级中断)。

5.4 电源管理:小主机不是笔记本,BIOS 设置决定稳定性

Intel N100/AMD 7640HS 迷你 PC 的 BIOS 中,常有“USB Selective Suspend”、“PCIe ASPM”等节能选项。开启后,系统空闲 5 分钟,网卡会进入低功耗状态,SSH 连接超时断开,nvidia-smi命令无响应。

必须进入 BIOS(开机按 Del/F2),关闭:

  • USB Power Saving Mode
  • PCIe ASPM Control
  • C-States(设为C1 only,禁用 C6/C7)

保存退出后,在 Ubuntu 中验证:

cat /sys/firmware/acpi/platform_profile # 应输出 "performance" cat /sys/bus/pci/devices/*/power/runtime_status | grep -v "active" # 不应有 "suspended"

这 4 个开关,没有一个在 DeepSeek Harness 文档里写明,但它们共同决定了你的 AI 工作站是“能用”还是“敢用”。我把它总结为一句话:AI 框架负责智能,Linux 系统负责生存。

6. 最后一步:验证你的远程 AI 工作站是否真正就绪

现在,整套系统已搭建完毕。但“完成”不等于“就绪”。我给你一套 5 分钟可执行的终验清单,每一条都对应一个真实故障场景:

验证项执行命令预期结果失败意味着
网络可达性ping -c 3 192.168.1.1033 packets receivednetplan 配置错误或网线未插牢
SSH 可信通道ssh -p 2222 -i ~/.ssh/id_ed25519_ai zhangsan@192.168.1.103 'echo OK'输出OK密钥权限错误或sshd_config未生效
GPU 可见性ssh -p 2222 zhangsan@192.168.1.103 'nvidia-smi --query-gpu=name --format=csv,noheader'输出NVIDIA GeForce RTX 4070驱动未安装或 CUDA 版本不匹配
AI 服务存活`curl -s http://192.168.1.103:8000/healthjq .status`输出"healthy"
Skill 可调用`curl -s http://192.168.1.103:8000/skill/file_reader -d '{}'jq .output`输出"文件内容摘要:# 用户手册..."

注意:所有命令必须在你的本地开发机(不是 Ubuntu Server)上执行。这才是“远程”的意义——你在 MacBook 上敲命令,AI 在远端小主机上运算。

如果全部通过,恭喜你,一台真正意义上的远程 AI 工作站已诞生。它没有花哨的图形界面,但每一行代码、每一个配置、每一次重启,都经过生产环境的千锤百炼。你可以用 VS Code Remote SSH 直接编辑skills/下的 Python 文件,保存即生效;可以用curl或 Postman 调用任意 Skill;可以把rag-engine目录打包,一键部署到另一台同配置机器。

这台小主机的价值,从此不再是“能跑 Ubuntu”,而是“能承载你的 AI 思维”。它不会主动提醒你更新,不会弹窗打扰你思考,不会因桌面卡顿而中断推理——它只是安静地、可靠地、7×24 小时地,等待你的下一个curl请求。

我在实验室贴了张便签在每台机器上:“Don’t touch the GUI. Trust the terminal.” —— 这不是教条,是 7 台机器、327 天、142 次故障排查后,最朴素的真理。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/8 12:00:24

治理型API层:面向应用、人员与Agent的API管理新范式

做后端和平台的朋友&#xff0c;最近应该都有同一种感觉&#xff1a;API 这个词被提起的频率越来越高&#xff0c;但真正能把自己的 API 管明白的团队并不多。尤其当 agent 类应用开始真正接入业务系统之后&#xff0c;原来的“人手动调接口”场景正在变成“程序自动调接口”甚…

作者头像 李华
网站建设 2026/10/8 11:59:59

Agent-Reach:让智能体从“只会聊天”到“真能办事”的触达链路设计

把智能体&#xff08;Agent&#xff09;从“只会聊天”变成“真能办事”&#xff0c;是我这一年多一直在折腾的事。Agent-Reach 这个名字&#xff0c;核心就落在 Reach 上——触达。大模型本身是个闭卷考生&#xff0c;再聪明也看不到考场外的资料&#xff0c;更别说动手改什么…

作者头像 李华
网站建设 2026/10/8 11:55:55

Java银行排号系统:并发控制与状态一致性实战

简介&#xff1a;这是一套面向计算机专业本科生的毕业设计级银行排号系统实战资源&#xff0c;完整覆盖Java桌面应用开发全流程&#xff0c;解决银行、政务大厅等场景下的客户分流与业务协同管理问题。资源包为69.98MB的RAR压缩文件&#xff0c;包含可运行Java源码、配套数据库…

作者头像 李华
网站建设 2026/10/8 11:54:26

Agentic Skills Framework 实战:用 superpowers 编排 Claude Code 与 Codex CLI 技能

1. 从“superpowers”说起&#xff1a;这套 agentic skills framework 到底在解决什么问题 第一次看到 “superpowers” 这个词&#xff0c;是在几个做 AI 编程工具链的朋友群里。有人甩了个链接&#xff0c;配文是“终于有人把 agentic skills framework 这件事讲明白了”。我…

作者头像 李华
网站建设 2026/10/8 11:53:17

控制即推断:从概率图模型到软贝尔曼方程的统一视角

1. 从一个反直觉的视角说起&#xff1a;控制问题为什么能当成推断问题 第一次接触“Control as Inference”这个概念时&#xff0c;我的反应大概是“这不是在硬凑吗”。控制是控制&#xff0c;推断是推断&#xff0c;一个是让系统按照预期动起来&#xff0c;一个是根据观测猜隐…

作者头像 李华
网站建设 2026/10/8 11:52:47

GPU推理并发数计算器:显存、算力、带宽约束下的容量规划

1. 从一张显卡到八张显卡&#xff1a;并发估算为什么总让人心里没底 做模型推理服务的人&#xff0c;几乎都绕不开一个问题&#xff1a;手上这几张卡&#xff0c;到底能扛住多少路并发&#xff1f;这个问题看起来简单&#xff0c;实际上一旦认真算起来&#xff0c;变量多到让人…

作者头像 李华