Sobre o advento do suporte CUDA na WSL 2

A Microsoft, respondendo a várias solicitações de usuários, introduziu em maio de 2020 na conferência Build um novo recurso do Windows Subsystem para Linux 2 (WSL 2) - suporte para aceleradores de vídeo. Isso permitirá que você execute aplicativos de computação ad-hoc no WSL 2. O suporte à GPU abrirá o caminho para ferramentas profissionais e ajudará a resolver tarefas no WSL 2 que atualmente só são possíveis no Linux. Agora, tarefas semelhantes podem ser resolvidas no Windows, usando os recursos da GPU.



É extremamente importante aqui que a WSL venha com suporte para a arquitetura de computação paralela de hardware e software NVIDIA CUDA .



O material que estamos publicando foi traduzido por especialistas da NVIDIA. Aqui, falaremos sobre o que esperar da CUDA na visualização pública do WSL 2.





Executando estruturas de AI do Linux em contêineres WSL 2



O que é WSL?



O WSL é um recurso do Windows 10 que permite usar as ferramentas de linha de comando do Linux diretamente no Windows sem precisar lidar com as complexidades da aplicação de uma configuração de inicialização dupla. O WSL é um ambiente em contêiner que está totalmente integrado ao Microsoft Windows. Isso permite que os aplicativos Linux sejam executados ao lado dos aplicativos tradicionais do Windows e dos aplicativos modernos distribuídos pela Microsoft Store.



A WSL é principalmente uma ferramenta para desenvolvedores. Se você estiver trabalhando em determinados projetos em contêineres Linux, isso significa que você pode fazer as mesmas coisas localmente, em um computador Windows, usando ferramentas Linux conhecidas. Geralmente, para executar esses aplicativos no Windows, você precisa gastar muito tempo configurando o sistema, precisa de estruturas, bibliotecas de terceiros. Agora, com o lançamento do WSL 2, tudo mudou. Graças ao WSL 2, o suporte total ao kernel do Linux chegou ao mundo do Windows.



A tecnologia de paravirtualização WSL 2 e GPU (Paravirtualização de GPU, GPU-PV) permitiu que a Microsoft levasse o suporte do Linux para Windows a um novo nível, possibilitando o lançamento de cargas de computação projetadas para a GPU. Abaixo, falaremos mais sobre como é o uso da GPU no WSL 2.



Se você estiver interessado no tópico de suporte para aceleradores de vídeo no WSL 2, consulte este material e este repositório.



CUDA para WSL



Para aproveitar os recursos da GPU no WSL 2, um driver de vídeo que suporte o Microsoft WDDM deve estar instalado no computador . Esses drivers são criados por fabricantes de placas de vídeo como a NVIDIA.



A tecnologia CUDA possibilita o desenvolvimento de programas para aceleradores de vídeo NVIDIA. Essa tecnologia é suportada no WDDM no Windows há muitos anos. O novo contêiner WSL 2 da Microsoft fornece recursos de computação acelerada por GPU das quais a tecnologia CUDA pode tirar vantagem, permitindo que programas baseados em CUDA sejam executados na WSL. Para mais informações, consulte o Guia do Usuário WSL CUDA.



O suporte WSL CUDA está incluído nos drivers da NVIDIA para WDDM 2.9. Esses drivers são fáceis de instalar no Windows. Os drivers do modo de usuário WSL CUDA (libcuda.so) ficam automaticamente disponíveis dentro do contêiner e o carregador pode detectá-los.



A equipe de desenvolvimento de drivers da NVIDIA adicionou suporte ao WDDM e GPU-PV ao driver CUDA. Isso é feito para que esses drivers funcionem em um ambiente Linux em execução no Windows. Esses drivers ainda estão no status de visualização; seu lançamento ocorrerá somente quando o lançamento oficial da WSL com suporte a GPU ocorrer. Detalhes sobre a versão do driver podem ser encontrados aqui .



A figura a seguir mostra um diagrama de como conectar o driver CUDA ao WDDM dentro de um convidado do Linux.





Driver WDDM no modo de usuário habilitado para CUDA em execução em um convidado Linux



Suponha que você seja um desenvolvedor que instalou a distribuição WSL na versão mais recente do Windows a partir do Fast Ring (versão 20149 ou anterior) Microsoft Windows Insider Program (WIP). Se você mudou para o WSL 2 e possui uma GPU NVIDIA, pode testar o driver e executar o código de computação da GPU no WSL 2. Para fazer isso, basta instalar o driver no sistema host do Windows e abrir o contêiner WSL. Aqui, sem esforços adicionais, você terá a oportunidade de trabalhar com aplicativos que usam CUDA. A figura a seguir mostra como um aplicativo TensorFlow usando recursos CUDA está sendo executado em um contêiner WSL 2.





Contêiner TensorFlow em execução no WSL 2



O fato de a tecnologia CUDA agora estar disponível no WSL torna possível executar aplicativos no WSL que anteriormente só podiam ser executados em um ambiente Linux normal.



A NVIDIA ainda está trabalhando ativamente neste projeto e fazendo melhorias nele. Entre outras coisas, estamos trabalhando para adicionar APIs ao WDDM que foram projetadas anteriormente exclusivamente para Linux. Isso levará ao fato de que na WSL, sem esforço adicional por parte do usuário, mais e mais aplicativos podem ser executados.



Outra questão que nos interessa é o desempenho. Como mencionado, o suporte da GPU no WSL 2 leva a tecnologia GPU-PV a sério. Isso pode afetar adversamente a velocidade de execução de pequenas tarefas na GPU, em situações em que o pipelining não será usado. Estamos trabalhando agora para reduzir ao máximo esses efeitos.



NVML



A tecnologia NVML não está incluída no pacote de driver original, estamos tentando corrigi-lo, planejando adicionar suporte para NVML e suporte para outras bibliotecas na WSL.



Começamos com o driver CUDA principal, que permitirá aos usuários executar a maioria dos aplicativos CUDA existentes, mesmo nos estágios iniciais do suporte a CUDA na WSL. Porém, alguns contêineres e aplicativos usam o NVML para obter informações da GPU antes mesmo de carregar o CUDA. É por isso que adicionar suporte a NVML na WSL é uma das nossas principais prioridades. É perfeitamente possível que em breve possamos compartilhar boas notícias sobre a solução desse problema.



Contêineres de GPU na WSL



Além do suporte do WSL 2 para DirectX e CUDA, a NVIDIA está trabalhando para adicionar suporte ao NVIDIA Container Toolkit (anteriormente chamado de nvidia-docker2) ao WSL 2. Os aplicativos de GPU em contêineres que os cientistas criam para executar em um ambiente Linux local ou na nuvem agora podem, sem fazer alterações, executar no WSL 2 em computadores executando o Windows.



Alguns pacotes WSL especiais não são necessários para isso. A biblioteca de tempo de execução NVIDIA (libnvidia-container) pode detectar dinamicamente a biblioteca libdxcore e usá-la quando o código é executado em um ambiente WSL 2 que suporta a aceleração da GPU. Isso acontece automaticamente após a instalação dos pacotes Docker e NVIDIA Container Toolkit, assim como no Linux. Isso permite que você, sem esforço adicional, execute contêineres no WSL 2 que usam o poder da GPU.



É altamente recomendável que aqueles que desejam usar esta opção --gpusinstalem a versão mais recente das ferramentas do Docker (19.03 ou mais recente). Para ativar o suporte ao WSL 2, siga as instruções para sua distribuição Linux e instale a versão mais recente disponível nvidia-container-toolkit.



Como funciona? Todas as tarefas específicas do WSL 2 são resolvidas usando a biblioteca libnvidia-container . Agora, esta biblioteca pode, em tempo de execução, detectar a presença de libdxcore.so e usar esta biblioteca para detectar todas as GPUs visíveis para essa interface.



Se você precisar usar essas GPUs no contêiner, usando libdxcore.so, acessará o local de armazenamento do driver, a pasta que contém todas as bibliotecas de drivers para o sistema host Windows e o WSL 2. A biblioteca libnvidia-container.so é responsável por configurar o contêiner de tal maneira que seria possível acessar corretamente o repositório de drivers. A mesma biblioteca é responsável por configurar as principais bibliotecas suportadas pelo WSL 2. Um diagrama disso é mostrado na figura a seguir.





O esquema para detectar e mapear o contêiner do repositório do driver usado pelo libnvidia-container.so no WSL 2



Além disso, isso difere da lógica usada fora do WSL. Esse processo é completamente abstraído usando libnvidia-container.so e deve ser o mais transparente possível para o usuário final. Uma das limitações desta versão anterior é que você não pode selecionar GPUs em ambientes com várias GPUs. Todas as GPUs estão sempre visíveis no contêiner.



No contêiner da WSL, você pode executar qualquer contêiner do NVIDIA Linux com o qual você já esteja familiarizado. A NVIDIA suporta as ferramentas e fluxos de trabalho Linux mais interessantes usados ​​por profissionais. Faça o download do contêiner de seu interesse no NVIDIA NGC e experimente.



Agora, mostraremos como executar contêineres TensorFlow e N-body no WSL 2, projetados para usar as GPUs NVIDIA para acelerar os cálculos.



Executando o contêiner de corpo N 



Instale o Docker usando o script de instalação:



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


Instale o NVIDIA Container Toolkit. O suporte ao WSL 2 está disponível a partir do nvidia-docker2 v2.3 e da biblioteca de tempo de execução libnvidia-container 1.2.0-rc.1.



Vamos configurar os repositórios stablee experimentale a chave GPG. Alterações no código de tempo de execução que são projetadas para suportar o WSL 2 estão disponíveis no repositório experimental.



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


Instale os pacotes de tempo de execução NVIDIA e suas dependências:



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


Abra o contêiner WSL e execute o daemon do Docker nele. Se tudo for feito corretamente, você poderá ver as mensagens de serviço dockerd.



user@PCName:/mnt/c$ sudo dockerd




Iniciando o daemon do Docker



Em outra janela da WSL, carregue e execute o contêiner de simulação de corpo N. É necessário que o usuário que está executando esta tarefa tenha autoridade suficiente para carregar o contêiner. Os seguintes comandos podem precisar ser executados usando o sudo. Na saída, você pode ver informações sobre a GPU.



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




Executando o contêiner de corpo N



Iniciar o contêiner TensorFlow



Vamos tentar no Docker, no ambiente WSL 2, outro contêiner popular - o TensorFlow.



Faça o download da imagem do TensorFlow Docker. Para evitar problemas na conexão com o Docker, execute o seguinte comando no modo sudo:



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


Vamos salvar a versão ligeiramente modificada do tutorial da GPU do Tutorial 15 do TensorFlow em disco no Csistema host. Essa unidade, por padrão, é montada no contêiner WSL 2 como /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("Shape:", shape, "Device:", device_name)
print("Time taken:", datetime.now() - startTime)


Abaixo estão os resultados da execução desse script, executado a partir de um disco montado em um contêiner C. O script foi executado, primeiro, usando a GPU e depois a CPU. Por conveniência, a produção aqui foi reduzida.



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




Resultados da execução do script matmul.py



Ao usar uma GPU em um contêiner WSL 2, é observado um aumento significativo na execução do código em comparação com a execução em uma CPU.



Vamos realizar outro experimento desenvolvido para estudar o desempenho da computação em GPU. Este é o código do manual do Jupyter Notebook. Depois de iniciar o contêiner, você verá um link para o servidor Jupyter Notebook.



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




Executando o Jupyter Notebook Agora



você deve conseguir executar as demos no ambiente do Jupyter Notebook. Observe que, para conectar-se ao Jupyter Notebook usando o Microsoft Edge, em vez de 127.0.0.1, uselocalhost.



Vá paratensorflow-tutorialse inicie o bloco de notasclassification.ipynb.



Para ver os resultados da aceleração dos cálculos usando a GPU, vá para o menuCell, selecioneRun Alle veja o log no Jupyter Notebook de 2 contêineres da WSL.





Jupyter Notebook Magazine



Esta demonstração, e algumas outras neste contêiner, permitem ver os problemas com a camada de virtualização, relacionados à carga adicional excessivamente alta no sistema ao resolver pequenas tarefas. Já falamos sobre isso acima. Como executamos modelos de tutorial muito pequenos aqui, o tempo de execução na GPU é menor que o tempo necessário para resolver problemas de sincronização. Ao resolver essas tarefas de "brinquedo" no WSL 2, a CPU pode ser mais eficiente que a GPU. Estamos empenhados em resolver esse problema, esforçando-nos para limitar suas manifestações apenas a cargas de trabalho muito pequenas, nas quais o pipelining não é aplicado.



Visão Geral da WSL



Para entender como o suporte à GPU foi adicionado no WSL 2, agora falamos sobre como é executar o Linux no Windows e como os contêineres veem o hardware.



A Microsoft introduziu a tecnologia WSL na Build em 2016. Essa tecnologia rapidamente encontrou uso generalizado e se tornou popular entre os desenvolvedores de Linux que precisavam executar aplicativos Windows como o Office, juntamente com ferramentas de desenvolvimento Linux e programas relacionados.



O WSL 1 permitiu executar executáveis ​​Linux não modificados. No entanto, ele usou uma camada de emulação de kernel do Linux que foi implementada como um subsistema de kernel do NT. Este subsistema tratou chamadas de aplicativos Linux, redirecionando-os para os mecanismos apropriados do Windows 10.



O WSL 1 era uma ferramenta útil, mas não era compatível com todos os aplicativos Linux porque precisava emular absolutamente todas as chamadas de sistema Linux. Além disso, as operações do sistema de arquivos foram lentas, o que levou a um desempenho inaceitavelmente baixo de alguns aplicativos.



Com isso em mente, a Microsoft decidiu seguir o caminho contrário e lançou o WSL 2, uma nova versão do WSL. Os contêineres do WSL 2 executam distribuições completas do Linux em um ambiente virtualizado, mas ainda aproveitam ao máximo o novo sistema de conteinerização do Windows 10.



Embora o WSL 2 use os serviços Hyper-V do Windows 10, não é uma máquina virtual tradicional, mas um mecanismo auxiliar de virtualização leve. Esse mecanismo é responsável pelo gerenciamento da memória virtual associada à memória física, permitindo que os contêineres WSL 2 aloquem memória dinamicamente acessando o sistema host do Windows.



Entre os principais objetivos da criação do WSL 2, é possível observar um aumento no desempenho do trabalho com o sistema de arquivos e garantir a compatibilidade com todas as chamadas do sistema. Além disso, o WSL 2 foi criado em um esforço para melhorar o nível de integração do WSL e do Windows. Isso permite que você trabalhe convenientemente com um sistema Linux em execução em um contêiner usando as ferramentas de linha de comando do Windows. Além disso, aumenta a usabilidade do sistema de arquivos host, que é montado automaticamente nos diretórios selecionados do sistema de arquivos contêiner.



O WSL 2 foi introduzido no Windows Insider Program como um recurso Preview e foi lançado na atualização mais recente do Windows 10, na versão 2004.



O WSL 2, a versão mais recente do Windows, possui ainda mais aprimoramentos que afetam tudo, desde pilhas de rede a mecanismos de armazenamento VHD básicos. Uma descrição de todos os novos recursos do WSL 2 está além do escopo deste material. Você pode aprender mais sobre eles nesta página, que compara o WSL 2 e o WSL 1.



WSL 2 do núcleo Linux



O kernel Linux usado no WSL 2 foi compilado pela Microsoft com base na ramificação estável mais recente, usando o código-fonte disponível em kernel.org. Este kernel foi especialmente ajustado para o WSL 2, otimizado para tamanho e desempenho para executar o Linux no Windows. O kernel é suportado pelo mecanismo do Windows Update. Isso significa que o usuário não precisa se preocupar em baixar as atualizações de segurança mais recentes e os aprimoramentos do kernel. Tudo isso é feito automaticamente.



A Microsoft suporta várias distribuições Linux na WSL. A empresa, seguindo as regras da comunidade de código-fonte aberto, publicou no repositório GitHub do WSL2-Linux-Kernel o código-fonte do kernel do WSL 2 com as modificações necessárias para a integração com o Windows 10. 



Suporte de GPU na WSL



A Microsoft adicionou suporte para GPUs reais usando a tecnologia GPU-PV nos contêineres WSL 2. Aqui, o núcleo gráfico do sistema operacional (dxgkrnl) chama os componentes do modo de usuário em execução na máquina virtual convidada para o driver do modo de kernel no host.



A Microsoft desenvolveu essa tecnologia como um recurso WDDM e várias versões do Windows foram lançadas desde o seu início. Este trabalho foi realizado com a assistência de fornecedores independentes de hardware (Independent Hardware Vendor, IHV). Os drivers gráficos da NVIDIA oferecem suporte ao GPU-PV desde os primeiros dias desta tecnologia nas versões de visualização dos produtos disponíveis no Windows Insider Program. Todas as GPUs NVIDIA atualmente suportadas podem ser acessadas por um sistema operacional Windows executando no modo convidado em uma máquina virtual executando o Hyper-V.



Para aproveitar os recursos de GPU-PV no WSL 2, a Microsoft precisou criar a base de sua estrutura gráfica para o convidado Linux: WDDM, com suporte ao protocolo GPU-PV. O novo driver da Microsoft está por trás do dxgkrnl, o sistema responsável pelo suporte ao WDDM no Linux. O código do driver pode ser encontrado no repositório WSL2-Linux-Kernel.



Dxgkrnl deve fornecer suporte à aceleração de GPU em contêineres WSL 2 no WDDM 2.9. A Microsoft diz que o dxgkrnl é um driver de GPU do Linux baseado no protocolo GPU-PV e que não tem nada a ver com um driver do Windows que tem um nome semelhante.



Atualmente, você pode baixar a versão de visualização do driver NVIDIA WDDM 2.9. Nos próximos meses, esse driver será distribuído via Windows Update na versão WIP do Windows, o que torna desnecessário baixar e instalar manualmente o driver.



Noções básicas sobre GPU-PV



O driver dxgkrnl disponibiliza, no modo de usuário do sistema convidado Linux, o novo dispositivo / dev / dxg. A camada de serviço do kernel D3DKMT, disponível no Windows, também foi portada, como parte da biblioteca dxcore, para o Linux. Ele se comunica com o dxgkrnl usando um conjunto de chamadas IOCTL privadas.



A versão de convidado do Linux do dxgkrnl se conecta ao kernel do dxg no host do Windows usando vários canais de barramento da VM. O kernel dxg no host processa o que vem do processo Linux, assim como o que vem dos aplicativos comuns do Windows usando o WDDM. Ou seja, o kernel dxg envia o que recebe ao KMD (Kernel Mode Driver, um driver de modo kernel exclusivo para cada HIV). O driver no modo kernel prepara o que recebe para enviar para a GPU de hardware. A figura a seguir mostra um diagrama simplificado da interação entre o dispositivo Linux / dev / dxg e o KMD.





Um diagrama simplificado de como os componentes host do Windows permitem que o dispositivo dxg funcione em um convidado do Linux



Quando se trata de fornecer esse comportamento nos convidados do Windows, os drivers da NVIDIA oferecem suporte ao GPU-PV no Windows 10 há algum tempo. As GPUs NVIDIA podem ser usadas para acelerar a saída de computação e gráficos em todos os aplicativos Windows 10 usando a camada de virtualização da Microsoft. O uso de GPU-PV também permite trabalhar com vGPU. Aqui estão alguns exemplos de aplicativos semelhantes:





Veja como é iniciar um aplicativo DirectX em um contêiner do Windows Sandbox usando um acelerador de vídeo NVIDIA GeForce GTX 1070.





A aceleração de gráficos no container Windows Sandbox é realizada pela NVIDIA GeForce GTX 1070



Suporte ao modo personalizado



Para adicionar suporte à renderização gráfica na WSL, a equipe de desenvolvimento correspondente da Microsoft também portou o componente do modo de usuário dxcore para o Linux.



A biblioteca dxcore fornece uma API que permite obter informações sobre as placas gráficas compatíveis com WDDM disponíveis no seu sistema. Essa biblioteca foi concebida como uma substituição de baixo nível de plataforma cruzada para a ferramenta para trabalhar com adaptadores DXGI no Windows e Linux. A biblioteca também abstrai o acesso aos serviços dxgkrnl (chamadas IOCTL nas chamadas Linux e GDI no Windows) usando a camada API D3DKMT, usada pela CUDA e outros componentes do modo usuário que dependem do suporte WSL WDDM.



Segundo a Microsoft, a biblioteca dxcore (libdxcore.so) estará disponível no Windows e Linux. A NVIDIA planeja adicionar suporte ao DirectX 12 e à API CUDA ao driver. Esses complementos têm como alvo os novos recursos da WSL disponíveis no WDDM 2.9. As duas bibliotecas de API serão conectadas ao dxcore para que possam instruir o dxg a organizar seus pedidos ao KMD no sistema host.



Experimente os novos recursos do WSL 2



Deseja usar o seu computador Windows para resolver problemas reais nos campos de aprendizado de máquina e inteligência artificial e, ao mesmo tempo, usar todas as comodidades de um ambiente Linux? Nesse caso, o suporte CUDA na WSL oferece uma ótima oportunidade para fazer isso. O ambiente da WSL é onde os contêineres CUDA Docker provaram ser o ambiente de computação mais popular entre os cientistas de dados.





Aqui você pode aprender mais sobre o uso da tecnologia CUDA na WSL. Aqui , no fórum dedicado à CUDA e à WSL, você pode compartilhar conosco suas impressões, observações e idéias sobre essas tecnologias.



Você já experimentou o CUDA no WSL 2?






All Articles