小白视角下校园网环境内基于WSL搭建远程算力平台

TL;DR

本文记录了我在校园网环境下,使用WSL搭建远程算力平台的全过程,适合初学者参考。

(一)背景

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 11
  • MacBook-Air:Mac OS Tahoe(实际上没有影响)

(二)准备

1. Windows电池性能设置

打开Windows设置-电源与电池-屏幕与睡眠,将插入电源后,闲置以下时间后关闭屏幕插入电源时,闲置以下时间后设备置于睡眠状态设置为从不

2. 下载NV驱动

到NVIDIA官网下载最新驱动,一般而言Game ReadyStudio版本区别不大

(三)WSL下载与初始化

1. 下载WSL

  1. 在Windows电脑中,按下Win+Q,搜索PowerShell,并使用管理员身份运行
  2. 输入wsl --install并按下回车,等待下载完成 第一次运行这行命令可能会失败,你需要依次排查下面的原因
  • BIOS未开启虚拟化 运行systeminfo | findstr /i "Virtualization",如果结果不是Virtualization Enabled In Firmware: Yes
    1. 先查找自己电脑如何开BIOS
    2. 进入BIOS面板后,开启Intel VT-xAMD SVM
  • DNS问题 DNS 能解析网页,但解析不了微软服务,WinHTTP优先使用不转发DNS的IPv6网关,我的解决办法是:暂时关闭IPv6网关,手动配置IPv4 DNS
    1. 打开设置-网络和 Internet-WLAN-[你连接的校园网]属性
    2. 点击DNS 服务器分配编辑按钮,将自动改为手动,打开IPv4、关闭IPv6并手动设置DNS为首选8.8.8.8,备选8.8.4.4
    3. 在命令行输入ipconfig /flushdns刷新配置 之后,请检查wsl的版本,确保在WSL2下运行
wsl -l -v

2. 初始化Ubuntu

  1. 第一次打开wsl系统会提示输入用户名和密码,按提示设置
  2. 输入(wsl)nvidia-smi,能看到自己的显卡即可
  3. 运行(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的配置

  1. 运行(wsl)curl -fsSL https://tailscale.com/install.sh | sh,等待下载完成
  2. 运行(wsl)sudo tailscale up,wsl会返回一个URL,在任意设备上访问并完成登陆
  3. 可以在网页端看到wsl的TailScale IP,在后文中以100.x.y.z代替

(五)SSH设置

  1. 安装ssh (wsl)
sudo apt update
sudo apt install openssh-server -y
sudo systemctl enable ssh
sudo systemctl start ssh
  1. 配置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
  1. 启动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远程设置

  1. 系统设置 打开(mac)nano ~/.ssh/config,写入
Host <Server Name>
    HostName 100.x.y.z
    User <你的WSL用户名>
    Port 2222
    IdentityFile ~/.ssh/id_ed25519
    ServerAliveInterval 60
  1. 安装VS Code插件Remote - SSH
  2. 点击左下角><符号,选择自定义的<Server Name>连接

(七)ML环境配置

我使用miniconda配置wsl上的环境

  1. 下载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
  1. 下载包
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
  1. 配置 Jupyter Lab
pip install jupyterlab
jupyter server password
# 启动
jupyter lab --no-browser --ip=0.0.0.0 --port=8888 --allow-root

(八)环境稳定

wsl需要保持定期活跃以确保不被校园网踢出,我通过运行一个Python脚本实现

  1. 创建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)
  1. 使用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
  1. 启动 (wsl)
sudo systemctl daemon-reload
sudo systemctl enable keepalive
sudo systemctl start keepalive
  1. 随后,可以使用sudo systemctl status keepalive查看运行状态

THANKS FOR READING.