window ML环境搭建问题记录

0 Windows版本选择

当前环境为 win10 LTSC 2016,版本号为1809,只能安装WSL1。
版本号1901以上才能安装WSL2。

WSL1与WSL2的区别为:
WSL1 没有Linux 内核,不支持docker;WSL2 是有Linux 内核的轻量化虚拟机,支持docker

配置ML环境需要使用nvidia-docker。遂安装最新win11。

略微搜索了一下,似乎有成功基于1809版本搭建环境的例子。考虑到时间成本,决定跟随微软官方教程操作。

系统安装环节:
主板:微星b450m 迫击炮
开机按del进入bios,安全 - Trusted Computing - Security Device Support 设置为 Enabed
开机按F11选择UEFI,快速从U盘启动。

1 WSL2环境安装

环境设置:
参考 Windows 安装WSL2全流程 启用window子系统及虚拟化章节。
安装:
参考资料:使用 WSL 在 Windows 上安装 Linux

# 查看在线版本
> wsl -l -o
以下是可安装的有效分发的列表。
使用 'wsl.exe --install <Distro>' 安装。

NAME                                   FRIENDLY NAME
Ubuntu                                 Ubuntu
Debian                                 Debian GNU/Linux
kali-linux                             Kali Linux Rolling
Ubuntu-18.04                           Ubuntu 18.04 LTS
Ubuntu-20.04                           Ubuntu 20.04 LTS
Ubuntu-22.04                           Ubuntu 22.04 LTS
OracleLinux_7_9                        Oracle Linux 7.9
OracleLinux_8_7                        Oracle Linux 8.7
OracleLinux_9_1                        Oracle Linux 9.1
openSUSE-Leap-15.5                     openSUSE Leap 15.5
SUSE-Linux-Enterprise-Server-15-SP4    SUSE Linux Enterprise Server 15 SP4
SUSE-Linux-Enterprise-15-SP5           SUSE Linux Enterprise 15 SP5
openSUSE-Tumbleweed                    openSUSE Tumbleweed
PS C:\Users\chenf>
# 手动指定安装版本
wsl --install -d Ubuntu-18.04

WslRegisterDistribution failed with error: 0x800701bc错误

解决方案:需要更新WSL内核。

WslRegisterDistribution failed with error: 0x80370102错误

# 错误信息
WslRegisterDistribution failed with error: 0x80370102
Please enable the Virtual Machine Platform Windows feature and ensure virtualization is enabled in the BIOS.

需要在bios中开启虚拟化,bios - Overlocking - cpu特征:SVM mode设置为Enable

确认成功

> wsl -l -v
  NAME            STATE           VERSION
* Ubuntu-18.04    Running         2

2 开发环境配置

提醒:以下操作均在Ubuntu上操作
设置 WSL 开发环境

Windows terminal使用:
打开微软终端,点右上角的下拉按钮,单击设置。 点左侧交互。 在右侧找到自动将所选内容复制到剪贴板选项,将开关按钮打开。

VsCode使用:
使用RemoteSSH连接到Ubuntu。

配置Git:

  • 更新
    sudo apt-get install git
    
  • 设置Git凭证
    git config --global  user.name "YourName"
    git config --global  user.email "YourEmail"
    

配置SSH:

  • 生成SSH
    生成ssh key的过程中不建议设置密码,直接enter跳过
    > ssh-keygen -t rsa -C "YourEmail"
    Generating public/private rsa key pair.
    Enter file in which to save the key (/home/username/.ssh/id_rsa):
    Created directory '/home/username/.ssh'.
    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:
    Your identification has been saved in /home/username/.ssh/id_rsa.
    Your public key has been saved in /home/username/.ssh/id_rsa.pub.
    
  • 注册到Github
    cat /home/username/.ssh/id_rsa.pub
    # 将全部打印内容注册到github中。
    # 测试ssh连通性
    ssh -T git@github.com # 用 ssh 连接 github
    The authenticity of host 'github.com' can't be established.
    ECDSA key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxx.
    Are you sure you want to continue connecting (yes/no)? yes
    Warning: Permanently added 'github.com,xxxxxxxx' (ECDSA) to the list of known hosts.
    Hi xxxxxx! You've successfully authenticated, but GitHub does not provide shell access.
    

配置局域网远程访问WSL2

由于有通过客厅电脑连接到此安装WSL2电脑的需求,需要配置局域网内访问WSL2的需求。
方法: 局域网A电脑通过ssh访问远程主机B的2222端口,局域网主机B的Windows系统中设置端口转发,将宿主机的2222端口映射到WSL2系统的2223端口,从而实现局域网内ssh连接到WSL2。
注意点:

  1. 22端口为常用端口,为避免与Windows中22端口重叠,需要修改WSL2中ssh使用2223端口;
  2. Windows系统设置端口转发
  3. Windows系统防火墙允许2222端口入站

WSL2操作记录
参考:VS Code+内网穿透 | 远程 WSL 开发解决方案

  1. 更新ssh
    WSL 上的 Ubuntu 其实已经默认安装了 openssh-server,然而这个软件配置是不完整的。为了正常使用,需要重新安装 openssh-server:
    # # 先卸载原有的 ssh
    sudo apt remove openssh-server
    # 重新安装新的 ssh
    sudo apt install openssh-server
    
  2. 配置 WSL 的 openssh-server
    修改 sshd_config 文件:
    # vim编辑器打开配置文件
    sudo vim /etc/ssh/sshd_config
    
    进入sshd_config后,需要修改的配置如下:
    Port 2223                   # 设置 ssh 访问 WSL 的端口号,端口 22 在 Windows 中别有他用,为了避免冲突需要单独设置
    PermitRootLogin yes         # 允许root远程登录
    PasswordAuthentication yes  # 密码验证登录
    AllowUsers *                # 远程登录时的用户,这里*是通配符
    
    修改完毕后,保存并退出 vim ,重启 ssh 服务:
    sudo service ssh --full-restart
    

    重新安装ssh后,记得要再执行一次配置SSH

  3. 远程主机BWindows系统中验证WSL2 ssh端口修改完成:
    > ssh ubuntu_userName@localhost -p 2223
    

Windows修改记录:
参考资料:如何在局域网的其他主机上中访问本机的WSL2

  1. 开启防火墙入站规则
    netsh advfirewall firewall add rule name=WSL2 dir=in action=allow protocol=TCP localport=2222
    
    也可以在 控制面板 --> Windows Defender 防火墙 --> 高级设置 --> 入站规则中设置
  2. 设置端口转发

    listenport和connectport设置成一样会有隐患,详见 WSL SSH kex_exchange_identification: read: Connection reset

    > netsh interface portproxy add v4tov4 listenport=2222 listenaddress=0.0.0.0 connectport=2223 connectaddress=localhost
    
    参数说明:
    listenport, 表示要监听的 Windows 端口
    listenaddress, 表示监听地址, 0.0.0.0 表示匹配所有地址, 比如Windows 既有Wifi网卡, 又有有线网卡, 那么访问任意两个网卡, 都会被监听到,当然也可以指定其中之一的IP的地址
    connectaddress ,要转发的地址, 这里设置为localhost, 是因为,我们可以通过localhost来访问WSL2, 如果暂不支持, 这里需要指定为 WSL2的IP地址
    connectport, 要转发到的端口
    
    查看端口转发情况:
    > netsh interface portproxy show all
    
    侦听 ipv4:                 连接到 ipv4:
    
    地址            端口        地址            端口
    --------------- ----------  --------------- ----------
    0.0.0.0         2222        localhost       2223 
    
  3. 局域网主机A上验证连接:
    > ssh ubuntu_userName@192.168.1.xxx -p 2222
    

原理:

  • Windows中防火墙设置是为了保证局域网主机A能够访问到远程主机B的50023端口;
  • WSL2通过虚拟网卡连接到window主机,但是每次重启时,虚拟网卡重新创建会导致WSL2主机的ip地址会变化,但是可以通过localhost访问,所以这也是在端口转发的时候为什么设置connectaddress=localhost
  • 但是使用localhost会有一个潜在的隐患,那就是如果Windows本地启动了指定端口, 这时WSL2中虽然可以使用相同的端口, 但是localhost:port将指向Windows的服务, WSL2的服务将会被覆盖!
  • 当然了, 如果我们配置端口转发时, 转发的IP(connectaddress)是WSL2的地址, 而不是localhost, 那么WSL2将会覆盖Windows的服务!
  • 22端口又是Windows中常用的,所以为了避免服务被覆盖,ssh服务改用不常用的端口。

坑爹

  1. WSL2系统会随着Windows终端的Console一同关闭
    这是产品设计时的默认设定,为了节约系统资源,如果您关闭了WSL的Console,实例会自动关闭。
    解决方案:一定不要关闭WSL的Console让WSL开机启动,后台运行,以减少唤醒时间

  2. VsCode的WSL插件会自动启动WSL2

    [2023-08-12 16:46:40.220] Run: C:\Windows\System32\wsl.exe -d Ubuntu-18.04 -e ...; const client = net.createConnection({ host: '127.0.0.1', port: 45209 }, ...;
    

    从WSL的日志可以看出,此插件会启动WSL2实例,并且使用的接口也自成一派。

  3. 设置Windows端口转发的时候,监听端口和转发不要设置成一样的,否则会出现kex_exchange_identification: read: Connection reset错误

3 ML环境配置

参考:WSL 中 ML 的 GPU 加速入门

先去Nvidia官网下载最新驱动,更新驱动后再根据参考连接中的步骤执行即可

ERROR:Docker Got permission denied while trying to connect to the Docker daemon socket at unix://

参考:解决Ubuntu18.04启动Docker“Got permission denied while trying to connect to the Docker daemon socket“问题

# 将当前用户添加到docker群组中
> sudo gpasswd -a $USER docker
Adding user xxxx to group docker
# 更新docker用户组
> newgrp docker

常用docker命令:
参考:一张脑图整理Docker常用命令

启动:

# 新建并启动
docker run [镜像名/镜像ID]
# 启动已终止容器
docker start [容器ID]

使用docker run新建容器时,如果未使用--names指定容器的名字,系统会随机分配一个。

查看容器

# 列出本机运行的容器
$ docker ps 
# 列出本机所有的容器(包括停止和运行)
$ docker ps -a

停止容器

# 停止运行的容器
docker stop [容器ID]
# 杀死容器进程
docker  kill [容器ID] 

进入容器:
进入容器有两种方式:

# 如果从这个 stdin 中 exit,会导致容器的停止
docker attach [容器ID]
# 交互式进入容器
docker exec -it [容器id] /bin/bash

进入容器通常使用第二种方式。

退出容器:

exit
Ctrl + D
Ctrl + P + Q

对于使用exec命令进入的容器,使用上述三种方法退出容器后,容器都不会关闭;
对于使用attach命令进入的容器,使用上述前两种方法退出会导致容器关闭,只有第三种不会关闭容器。

删除容器

docker  rm [容器ID]

测试对GPU的调用

注意: 使用ssh连接到WSL2时,无法使用nvidia-smi,执行命令测试模型时,不会调用到GPU。但是直接使用WSL2的Console时则一切正常。

# SSH连接
> nvidia-smi

Command 'nvidia-smi' not found, but can be installed with:

sudo apt install nvidia-340
sudo apt install nvidia-utils-390

# 直接在WSL2 Console中执行
> nvidia-smi
Sun Aug 13 11:34:31 2023
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 535.98.01              Driver Version: 536.99       CUDA Version: 12.2     |
|-----------------------------------------+----------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |         Memory-Usage | GPU-Util  Compute M. |
|                                         |                      |               MIG M. |
|=========================================+======================+======================|
|   0  NVIDIA GeForce GTX 1660        On  | 00000000:26:00.0 Off |                  N/A |
| 37%   45C    P0              22W / 120W |    896MiB /  6144MiB |      1%      Default |
|                                         |                      |                  N/A |
+-----------------------------------------+----------------------+----------------------+

+---------------------------------------------------------------------------------------+
| Processes:                                                                            |
|  GPU   GI   CI        PID   Type   Process name                            GPU Memory |
|        ID   ID                                                             Usage      |
|=======================================================================================|
|    0   N/A  N/A        32      G   /Xwayland                                 N/A      |
|    0   N/A  N/A       338      C   /python3.6                                N/A      |
+---------------------------------------------------------------------------------------+

对于在WSL2的Console中通过命令创建的docker,通过ssh连接到WSL2后进入容器内还是能正常使用nvidia-smi的。

测试:
使用参考链接中命令安装 NVIDIA 容器工具包 后,测试demo中的resnet模型。
可从nvidia-smi和Windows任务管理器中观察到GPU能被调用到。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值