适用于Linux 2的Windows子系统上的CUDA

适用于Linux 2的Windows子系统上的CUDAhtml

Announcing CUDA on Windows Subsystem for Linux 2python

为了响应大众的需求,微软在2020年5月的构建会议上宣布了WindowsSubsystem for Linux2(WSL2)的一个新特性——GPU加速。这一特性为许多计算应用程序、专业工具和工做负载打开了大门,目前只有Linux才有,但如今能够在Windows上按原样运行,并从GPU加速中获益。             git

最重要的是,NVIDIA CUDA加速度如今来到了WSL。在这篇文章中,将讨论在WSL 2的公共预览中对CUDA的指望。github

What is WSL?

WSL是Windows 10的一个特性,使可以直接在Windows上运行本机Linux命令行工具,而不须要复杂的双引导环境。在内部,WSL是一个与Microsoft Windows操做系统紧密集成的容器化环境。这使得能够在传统的Windows桌面和现代商店应用程序的同时运行Linux应用程序。             docker

WSL主要是开发人员的工具。若是正在Linux容器中处理计算工做负载,则可使用熟悉的本地Linux工具在Windows PC上本地开发和测试工做负载。一般,这些应用程序须要大量的黑客、第三方框架和库才能在Windows系统上运行。全部这些都随WSL 2而改变,WSL 2为Windows世界带来了完整的Linux内核支持。             shell

借助WSL 2和GPU半虚拟化(GPU-PV)技术,微软正在为Windows上的Linux支持添加另外一个功能,容许运行针对GPU硬件的计算工做负载。在本文后面,将更详细地介绍WSL 2以及GPU是如何添加到其中的。             编程

有关更多信息,请参见DirectX进入Windows Linux子系统和GitHub中的WSL2 Linux Kernel/driver/gpu目录。windows

CUDA in WSL

要利用WSL 2中的GPU,目标系统必须安装支持Microsoft WDDM模型的GPU驱动程序。这些驱动程序由NVIDIA等GPU硬件供应商提供。             api

CUDA容许编程NVIDIA GPU。几十年来,在Windows图形中的WDDM模型中获得了支持。新的Microsoft WSL 2容器提供了GPU加速,CUDA能够利用在WSL内部运行CUDA工做负载。有关更多信息,请参阅《关于WSL的CUDA用户指南》。              浏览器

在WSL中对CUDA的支持包含在针对WDDM 2.9模型的NVIDIA显示驱动程序中。只须要在Windows主机上安装驱动程序。WSL中的CUDA用户模式驱动程序(利布达)自动映射到容器内并添加到该容器的加载程序搜索路径中。             

NVIDIA驱动程序开发团队为CUDA驱动程序添加了对WDDM模型和GPU-PV的支持,以便可以在Windows上的Linux上运行。仍然是一个预览驱动程序,在Windows 10中WSL的官方GPU支持发布以前不会发布。有关该版本的更多信息,请参阅CUDA WSL 2下载。             

图2显示了如何将CUDA驱动程序插入Linux客户机中的新WDDM模型的简单图。

 

Figure 1. Stack image showing layers involved while running Linux AI frameworks in WSL 2 containers.

 

Figure 2. A diagram of the WDDM model supporting CUDA user mode driver running inside Linux guest.

若是是从Microsoft Windows Insider程序的Fast Ring(build 20149或更高版本)在最新的Windows版本上安装了WSL发行版并将容器设置为以WSL 2模式运行的开发人员,而且若是是PC中NVIDIA GPU的受启发全部者,则能够尝试该驱动程序并在WSL 2中运行工做负载。只需在Windows主机操做系统上安装驱动程序,而后打开WSL容器。CUDA将在那里与CUDA应用程序一块儿工做,而不须要任何额外的努力。图3显示了在WSL 2容器中运行CUDA TensorFlow工做负载的屏幕截图。

 

WSL中的GPU为当前仅在本机Linux环境中运行的各类CUDA计算应用程序打开了大门。             

英伟达仍在积极地进行这一项目,并做出调整。除此以外,正在努力将之前特定于Linux的api引入WDDM层,以便愈来愈多的应用程序能够开箱即用地处理WSL。             

另外一个焦点是表现。如前所述,WSL 2 GPU支持极大地利用了GPU-PV,能够影响较小的GPU工做负载,而无需任何流水线。如今,正在尽量减小这些开销。

NVML

NVML不包含在初始驱动程序包中,对此存在一些问题。为了解决这个问题,计划将NVML和其库一块儿引入WSL。             

首先启动了核心CUDA驱动程序,让能够在这个早期预览中尝试大部分现有的工做负载。意识到一些容器和应用程序甚至在加载CUDA以前就利用NVML查询GPU信息。这就是为何把NVML放在WSL的首要任务中。请继续关注此主题的更多更新。

GPU containers in WSL

除了DirectX和CUDA支持以外,NVIDIA还在WSL 2中添加了对NVIDIA容器工具包(之前是NVIDIA-docker2)的支持。数据科学家准备在Linux本地硬件下运行或在云中执行的容器化GPU工做负载,如今能够在Windows PC上的WSL2中运行。             

不须要特定的WSL包。NVIDIA运行时库(libnvidia容器)能够动态检测libdxcore,并在具备GPU加速的WSL 2环境中运行时使用。这是在Docker和NVIDIA容器工具包包安装以后自动发生的,就像在Linux上同样,容许GPU加速的容器以开箱即用的方式运行。             

建议使用Docker工具的最新版本(19.03或更高版本),以利用对--gpus选项的额外支持。要启用WSL 2支持,请按照针对Linux发行版的GitHub repo上的自述步骤进行操做,并安装可用的最新版本。             

那么是如何工做的呢?全部特定于WSL 2的工做都由libnvidia容器库处理。这个库如今可以在运行时检测libdxcore.so文件并用来检测全部暴露在这个接口上的gpu。              

若是须要在容器中使用这些gpu,则使用如下命令查询驱动程序存储的位置:包含Windows主机和WSL 2的全部驱动程序库的文件夹libdxcore.so文件. 这取决于libnvidia-container设置容器以便正确映射驱动程序存储,并为WSL 2 GPU支持的核心库进行设置,如图4所示。

 

Figure 4. Discovery and mapping scheme used by libnvidia-container.so on WSL 2.

并且,这与WSL以外使用的逻辑不一样。这彻底是由libnvidia-container.so抽象出来的-对最终用户来讲应该尽量透明。此早期版本的一个限制是在多GPU环境中缺乏GPU选择:容器中始终可见全部GPU。             

如下是能够在WSL容器中运行的内容:目前熟悉的任何NVIDIA Linux容器。NVIDIA支持专业人士使用的大多数现有Linux工具和工做流。从NVIDIA NGC下载最喜欢的容器工做负载并进行尝试。              

在下一节中,将描述如何在WSL 2中运行TensorFlow和n-body容器,同时使用NVIDIA GPUs加速工做负载。

Running the N-body container

使用Docker安装脚本安装Docker:

user@PCName:/mnt/c$ curl https://get.docker.com | sh

安装NVIDIA容器工具包。从nvidia-docker2 v2.3和底层运行库libnvidia container 1.2.0-rc.1开始,就提供了WSL 2支持。             

创建稳定的实验库和GPG密钥。支持WSL 2的运行时更改在实验存储库中可用。

user@PCName:/mnt/c$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID)
user@PCName:/mnt/c$ curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add -
user@PCName:/mnt/c$ curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
user@PCName:/mnt/c$ curl -s -L https://nvidia.github.io/libnvidia-container/experimental/$distribution/libnvidia-container-experimental.list | sudo tee /etc/apt/sources.list.d/libnvidia-container-experimental.list

安装NVIDIA运行时包及其依赖项:

user@PCName:/mnt/c$ sudo apt-get update
user@PCName:/mnt/c$ sudo apt-get install -y nvidia-docker2

打开WSL容器并在那里启动Docker守护进程。应该看到dockerd服务输出。

user@PCName:/mnt/c$ sudo dockerd

physical GPU (device: 0, name: GeForce GTX 1070, pci bus id: 0000:01:00.0, compute capability: 6.1)" src="file:///C:/Users/JIANMI~1.HAS/AppData/Local/Temp/msohtmlclip1/01/clip_image010.gif" border="0" v:shapes="图片_x0020_13">

 

Figure 5. Starting the Docker daemon.

在另外一个WSL容器窗口中,下载并启动N-body仿真容器。确保用户有足够的权限下载容器。可能须要在sudo中运行如下命令。GPU在输出中突出显示。

user@PCName:/mnt/c$ docker run --gpus all nvcr.io/nvidia/k8s/cuda-sample:nbody nbody -gpu -benchmark

 

Figure 6. Starting the N-body simulation container.

Running the TensorFlow container

尝试另外一个流行的容器:WSL 2中Docker中的TensorFlow。             

下载TensorFlow Docker图像。为了不Docker链接问题,该命令在sudo中运行。

user@PCName:/mnt/c$ docker pull tensorflow/tensorflow:latest-gpu-py3

保存稍微修改过–使用主机驱动器C上TensorFlow教程中的GPU,默认状况下,该驱动器在WSL2容器中映射为/mnt/C。

user@PCName:/mnt/c$ vi ./matmul.py
import sys
import numpy as np
import tensorflow as tf
from datetime import datetime
device_name = sys.argv[1]  # Choose device from cmd line. Options: gpu or cpu
shape = (int(sys.argv[2]), int(sys.argv[2]))
if device_name == "gpu":
    device_name = "/gpu:0"
else:
    device_name = "/cpu:0"
tf.compat.v1.disable_eager_execution()
with tf.device(device_name):
    random_matrix = tf.random.uniform(shape=shape, minval=0, maxval=1)
    dot_operation = tf.matmul(random_matrix, tf.transpose(random_matrix))
    sum_operation = tf.reduce_sum(dot_operation)
 
 
startTime = datetime.now()
with tf.compat.v1.Session(config=tf.compat.v1.ConfigProto(log_device_placement=True)) as session:
        result = session.run(sum_operation)
        print(result)
 
# Print the results
print("Shape:", shape, "Device:", device_name)
print("Time taken:", datetime.now() - startTime)

在GPU和CPU上运行此脚本的结果以下所示,该脚本是从安装的驱动器C启动的。为了简单起见,减小了输出。

user@PCName:/mnt/c$ docker run --runtime=nvidia --rm -ti -v "${PWD}:/mnt/c" tensorflow/tensorflow:latest-gpu-jupyter python /mnt/c/matmul.py gpu 20000

 

Figure 7. Running the matmul.py script.

当在WSL 2容器中使用GPU进行先前的计算场景时,会有显著的加速。             

下面是另外一个演示,看看GPU加速的工做:Jupyter笔记本教程。当容器启动时,应该会看到打印到笔记本服务器的连接。

user@PCName:/mnt/c$ docker run -it --gpus all -p 8888:8888 tensorflow/tensorflow:latest-gpu-py3-jupyter   

 

Figure 8. Launching the Jupyter notebook.

如今应该能够在Jupyter笔记本上运行演示示例了。链接到笔记本时,请当心使用Microsoft Edge浏览器中的localhost,而不是127.0.0.1。              

导航到tensorflow教程并运行分类.ipynb笔记本。             

要查看Windows PC的GPU加速的工做,请导航到“单元格”菜单,选择“所有运行”,而后检查Jupyter笔记本的WSL 2容器中的日志。

physical GPU (device: 0, name: GeForce GTX 1070, pci bus id: 0000:01:00.0, compute capability: 6.1)" src="file:///C:/Users/JIANMI~1.HAS/AppData/Local/Temp/msohtmlclip1/01/clip_image018.gif" border="0" v:shapes="图片_x0020_27">

 

Figure 9. The Jupyter notebook log.

这个演示和这个容器中的其一些演示突出了小提交的虚拟化层当前的开销问题,前面也提到过。与这些玩具模型相关联的提交会致使GPU运行时比同步开销自己要短。在WSL 2上的这些极小型模型案例中,CPU时间可能比GPU时间更好。目前正在对其进行优化,并应仅限于较小的非流水线工做负载。

WSL overview

为了了解GPU是如何添加到WSL 2的,如今讨论Windows上的Linux是什么以及硬件是如何暴露给容器的。             

微软在2016年的构建会议上引入了WSL。很快得到了发展势头,并成为Linux开发人员中的一个流行工具,但愿在运行Linux开发工具和目标工做负载的同时运行Office等Windows应用程序。             

WSL 1容许运行未修改的Linux二进制文件。可是,仍然使用Linux内核仿真层,是做为NT内核内的子系统实现的。该子系统经过未来自Linux应用程序的调用转发到相应的Windows 10功能来处理这些调用。             

WSL 1是一个颇有用的工具,但并不兼容全部的Linux应用程序,由于须要模拟可能每一个Linux系统调用。通常来讲,文件系统的访问也很慢,这致使了一些实际应用程序没法接受的性能。             

考虑到这一点,微软决定走另外一条路,推出了WSL 2,一个新版本的WSL。WSL 2容器在虚拟化环境中运行完整的Linux发行版,同时仍然充分利用Windows 10新容器系统的优势。              虽然使用Windows 10的Hyper-V服务,WSL 2仍然不是一个传统的VM,而是一个轻量级的实用VM。该实用程序管理虚拟地址备分内存,容许wsl2容器从主机Windows系统动态分配内存。             

WSL 2的一些主要目标是提升文件系统性能并支持彻底的系统调用兼容性。还具备更好的总体Windows主机系统集成。容许从Windows shell到运行在容器内的Linux系统的快捷方式,以及对自动装载到容器文件系统的选定目录的主机文件系统的访问。              

WSL2做为WindowsInsider程序的预览功能启用,并做为最新的Windows10更新版本2004发布。             

在最新的Windows版本中,WSL 2容器有了更多的改进,从网络堆栈到底层存储VHD。描述全部细节将超出本文的范围。有关WSL 2容器的一些有趣和使人兴奋的新特性的更多信息,请参阅比较wsl2和WSL 1。

WSL 2 Linux kernel

WSL 2中的Linux内核是由微软基于kernel.org网站. 这个内核专门针对WSL 2进行了调整,针对大小和性能进行了优化,以在Windows上提供Linux体验。内核由Windows Update提供服务,这意味着无需本身管理便可得到最新的安全修复和内核改进。             

微软在WSL中支持几个Linux发行版。遵循开放源代码社区的规则,WSL2内核源代码是公共的,能够在WSL2 Linux内核GitHub repo上使用,其中包含容许系统与Windows 10主机集成所需的修改。

GPU in WSL

微软开发人员正在经过GPU-PV技术将真正的GPU硬件支持引入WSL 2容器,在那里OS图形内核(dxgkrnl)将运行在guest VM内的用户模式组件调用封送到主机上的内核模式驱动程序。             

在独立硬件供应商(IHV)的帮助下,微软开发了这项技术,做为其WDDM图形驱动程序模型的一项功能。NVIDIA图形驱动程序自Windows操做系统的Windows Insider程序中的功能预览早期起就支持GPU-PV。全部当前支持的NVIDIA gpu均可以暴露给运行在Hyper-V VM guest中的Windows操做系统。             

对于WSL 2可以利用GPU-PV的能力,微软必须在Linux客户机中实现其图形框架的基础:使用GPU-PV协议的WDM模型。新的微软驱动程序支持Linux上的WDDM模型dxgkrnl。还能够做为WSL2 Linux内核GitHub repo中的源代码项目使用。             

dxgkrnl驱动程序有望为WDDM 2.9版本的wsl2容器带来对GPU加速的支持。微软解释说,dxgkrnl是一个基于GPU-PV协议的Linux GPU驱动程序,与同名的Windows驱动程序没有任何共同之处。             

目前,能够下载预览版的NVIDIA WDDM 2.9驱动程序。在接下来的几个月里,NVIDIA WDDM 2.9驱动程序将从Windows Update的WIP版本中分发,这使得手动下载和安装驱动程序变得没必要要。

GPU-PV in a nutshell

dxgkrnl驱动程序在Linux guest中将新的/dev/dxg设备公开给用户模式。D3DKMT内核服务层已经在Windows上提供,也做为dxcore库的一部分被移植到Linux上。使用一组私有IOCTL调用与dxgkrnl通讯。              

来宾Linux版本的dxgkrnl使用多个虚拟机总线通道链接到Windows主机上的dxg内核。主机上的dxg内核对待Linux进程提交的方式与运行在WDDM模型中的本地Windows应用程序提交进程的方式相同。将发送到KMD(一个特定于IHV的内核模式驱动程序),KMD准备并将提交给硬件GPU。图10显示了这种通讯信道的简化图。

 

Figure 10. A simplified diagram showing Windows host components backing the new graphics dxg device in Linux guest.

NVIDIA驱动程序在许多版本中都支持Windows 10 GPU-PV和Windows来宾。NVIDIA GPU可用于在全部使用Microsoft虚拟化层的最终用户Windows 10应用程序中加速计算和图形,并使用GPU-PV功能添加vGPU:

11显示了在NVIDIA GeForce GTX 1070 GPU上的Windows沙盒容器中运行示例DirectX应用程序的示例。

 

Figure 11. Windows Sandbox container gets GPU acceleration on an NVIDIA GeForce GTX 1070 GPU.

User mode support

为了在WSL中启用图形,Windows图形团队还将一个用户模式组件移植到Linux:dxcore。             

dxcore库提供了一个API函数,用于枚举系统中符合WDDM的图形适配器。旨在做为Windows和Linux中DXGI适配器枚举的跨平台、低级替代品。还使用D3DKMT层API抽象了对dxgkrnl服务(Linux上的IOCTLs和Windows上的GDI调用)的访问,CUDA和其依赖WSL中WDDM模型支持的用户模式组件使用该API。             

据微软称,dxcore(libdxcore.so文件)库将在Windows和Linux上均可用。NVIDIA计划在驱动程序中添加对DirectX 12和cudapi的支持,目标是WDDM 2.9模型的新WSL特性。两个API库都将连接到dxcore,以即可以指示dxg内核将请求封送到主机上的KMD。

Try it today

若是想使用Windows PC在Linux环境中进行真正的ML和AI开发,WSL中对CUDA的支持将为带来一个使人兴奋的机会。WSL是Docker CUDA容器被证实是数据科学家中最流行的计算环境之一。             

加入Microsoft Windows Insider程序以访问启用GPU加速的WSL 2预览。             

下载最新的NVIDIA驱动程序,安装,并尝试在WSL 2中运行CUDA容器化工做负载。

相关文章
相关标签/搜索