(一)背景
1.目的与动机
我计划学习机器相关的知识并熟练大致的架构、代码,想要使用MacBook编写代码,但是显然用M芯片跑ML十分慢,恰好我又有一台NVIDIA 4070 Laptop的Windows笔记本电脑,于是便想在Win上搭建一个类似服务器的平台,通过Mac上的VS Code远程ssh到Linux上用GPU加速代码。
2. 技术路线
将4070 Laptop主机搭建为一台无头服务器,Windows系统作为宿主,借助WSL和内网穿透实现校园网下的远程连接
3. 我的平台
ASUS 天选5 pro:Windows 11MacBook-Air:Mac OS Tahoe(实际上没有影响)
(二)准备
1. Windows电池性能设置
打开Windows设置-电源与电池-屏幕与睡眠,将插入电源后,闲置以下时间后关闭屏幕和插入电源时,闲置以下时间后设备置于睡眠状态设置为从不
2. 下载NV驱动
到NVIDIA官网下载最新驱动,一般而言Game Ready和Studio版本区别不大
(三)WSL下载与初始化
1. 下载WSL
- 在Windows电脑中,按下
Win+Q,搜索PowerShell,并使用管理员身份运行 - 输入
wsl --install并按下回车,等待下载完成 第一次运行这行命令可能会失败,你需要依次排查下面的原因
- BIOS未开启虚拟化
运行
systeminfo | findstr /i "Virtualization",如果结果不是Virtualization Enabled In Firmware: Yes- 先查找自己电脑如何开BIOS
- 进入BIOS面板后,开启
Intel VT-x或AMD SVM
- DNS问题
DNS 能解析网页,但解析不了微软服务,
WinHTTP优先使用不转发DNS的IPv6网关,我的解决办法是:暂时关闭IPv6网关,手动配置IPv4 DNS- 打开
设置-网络和 Internet-WLAN-[你连接的校园网]属性 - 点击
DNS 服务器分配的编辑按钮,将自动改为手动,打开IPv4、关闭IPv6并手动设置DNS为首选8.8.8.8,备选8.8.4.4 - 在命令行输入
ipconfig /flushdns刷新配置 之后,请检查wsl的版本,确保在WSL2下运行
- 打开
wsl -l -v
2. 初始化Ubuntu
- 第一次打开
wsl系统会提示输入用户名和密码,按提示设置 - 输入(wsl)
nvidia-smi,能看到自己的显卡即可 - 运行(wsl)
sudo nano /etc/wsl.conf,加上(如果没有)
[boot]
systemd=true
随后按下Ctrl+o+Enter保存,Ctrl+x退出
4. 运行(windows)wsl --shutdown,重启wsl
(四)内网穿透
使用TailScale进行内网穿透
1. Windows和Mac
到官网下载TailScale(www.tailscale.com),完成注册、登陆至同一账号即连接
2. WSL的配置
- 运行(wsl)
curl -fsSL https://tailscale.com/install.sh | sh,等待下载完成 - 运行(wsl)
sudo tailscale up,wsl会返回一个URL,在任意设备上访问并完成登陆 - 可以在网页端看到wsl的TailScale IP,在后文中以
100.x.y.z代替
(五)SSH设置
- 安装ssh (wsl)
sudo apt update
sudo apt install openssh-server -y
sudo systemctl enable ssh
sudo systemctl start ssh
- 配置ssh
运行(wsl)
sudo nano /etc/ssh/sshd_config在文件中写入
Port 2222
PasswordAuthentication yes
PubkeyAuthentication yes
PermitRootLogin no
UsePAM yes
ListenAddress 0.0.0.0
PidFile /run/sshd.pid
- 启动sshd 运行 (wsl)
sudo mkdir -p /run/sshd
sudo chmod 0755 /run/sshd
sudo systemctl restart ssh
systemctl status ssh
大概可以看到sshd正常运行,如果不行,那就说明systemd在运行sshd时在装死,我们要强行掐醒它
先检查(wsl)sudo /usr/sbin/sshd -D -p 2222 -f /etc/ssh/sshd_config:
- 如果有类似
/etc/ssh/sshd_config line 23: Bad configuration option: ListenAddress的输出,说明配置写错了,你得去改配置 - 如果没有输出,另外打开一个wsl窗口,运行(wsl)
ssh -p 2222 user@127.0.0.1(让它自己连自己),如果成功了就跳到下面一步,失败的话: 我们再运行 (wsl)
sudo mkdir -p /etc/init.d
sudo nano /etc/init.d/start-sshd.sh
写入
#!/bin/bash
/usr/sbin/sshd -D -p 2222
然后再(wsl)sudo chmod +x /etc/init.d/start-sshd.sh
退出wsl,在PowerShell中运行(windows)wsl -d Ubuntu -u root /etc/init.d/start-sshd.sh
再次启动wsl,应该就能复活
4. Mac的连接
运行(确保.ssh目录存在)
(wsl)
mkdir -p ~/.ssh
chmod 700 ~/.ssh
首先在Mac上生成公钥(mac)ssh-keygen -t ed25519,你可以输入密码进行保护,直接按Enter省略密码
接下来我们要将公钥传递给wsl,有下面两种途径
a. 自动复制
+ (mac)ssh-copy-id -p 2222 user@100.x.y.z(你需要将100.x.y.z替换为你自己wsl的TailScale Ip)
+ 按要求输入密码即可
b. 手动写入
+ 在Mac上查看公钥(mac)cat ~/.ssh/id_ed25519.pub,得到大概如ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB... yourname@mac
+ 打开wsl内的配置文件(wsl)
mkdir -p ~/.ssh
nano ~/.ssh/authorized_keys
+ 写入公钥的全文ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB... yourname@mac
+ 更改访问权限
(wsl)
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
最后,进入(wsl)sudo nano /etc/ssh/sshd_config,更改PasswordAuthentication yes->PasswordAuthentication no,运行systemctl restart ssh重启服务
5. 测试
在Mac上运行:
(mac)
nc -vz 100.x.y.z 2222
ssh -p 2222 user@100.x.y.z
应该能直接连接
(六)VS Code远程设置
- 系统设置
打开(mac)
nano ~/.ssh/config,写入
Host <Server Name>
HostName 100.x.y.z
User <你的WSL用户名>
Port 2222
IdentityFile ~/.ssh/id_ed25519
ServerAliveInterval 60
- 安装VS Code插件
Remote - SSH - 点击左下角
><符号,选择自定义的<Server Name>连接
(七)ML环境配置
我使用miniconda配置wsl上的环境
- 下载miniconda
mkdir -p ~/miniconda3
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda3/miniconda.sh
bash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3
rm -rf ~/miniconda3/miniconda.sh
~/miniconda3/bin/conda init bash
source ~/.bashrc
- 下载包
pip install numpy pandas scipy scikit-learn sympy \
-i https://pypi.tuna.tsinghua.edu.cn/simple
# 先运行 nvidia-smi 查看cuda版本,安装`cu121`中xxx的版本号不高于cuda版本
pip3 install torch torchvision torchaudio \
--index-url https://download.pytorch.org/whl/cu121
pip install matplotlib seaborn tensorboard tqdm \
-i https://pypi.tuna.tsinghua.edu.cn/simple
pip install opencv-python-headless pillow jupyterlab ipykernel \
-i https://pypi.tuna.tsinghua.edu.cn/simple
pip install cupy-cuda12x
python -m ipykernel install --user --name=torch_env --display-name "Python (Torch Env)"
随后使用简单的Python脚本校验环境
cuML相关库的依赖十分复杂,且在生产环境中容易炸环境,于是使用conda安装一个独立的环境
conda create -n rapids_env -c rapidsai -c conda-forge -c nvidia \
cuml=24.12 python=3.10 cuda-version=12.1
- 配置
Jupyter Lab
pip install jupyterlab
jupyter server password
# 启动
jupyter lab --no-browser --ip=0.0.0.0 --port=8888 --allow-root
(八)环境稳定
wsl需要保持定期活跃以确保不被校园网踢出,我通过运行一个Python脚本实现
- 创建Python脚本
(wsl)
sudo nano /home/dmin/keep_alive.py写入
import time
import requests
import datetime
def log(msg):
print(f"[{datetime.datetime.now()}] {msg}")
def online():
try:
r = requests.get("https://www.baidu.com", timeout=5)
return r.status_code == 200
except:
return False
while True:
if not online():
log("Network offline! (此处可扩展自动重连逻辑)")
break
else:
pass
time.sleep(180)
- 使用systemd创建服务文件
(wsl)
sudo nano /etc/systemd/system/keepalive.service写入以下内容
[Unit]
Description=Campus Network Keep Alive Service
After=network.target
[Service]
User=dmin # 你的用户名
ExecStart=/usr/bin/python3 /home/dmin/keep_alive.py # 改为
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
- 启动 (wsl)
sudo systemctl daemon-reload
sudo systemctl enable keepalive
sudo systemctl start keepalive
- 随后,可以使用
sudo systemctl status keepalive查看运行状态