O cGPU do isola recursos de GPU e permite que vários containers compartilhem uma única placa de GPU. Esse componente do Container Service for Kubernetes (ACK) foi projetado para cargas de trabalho de computação de alto desempenho (HPC), como machine learning, deep learning e computação científica. O recurso acelera tarefas computacionais ao utilizar os recursos de GPU com maior eficiência. Este tópico descreve como instalar e usar o cGPU do .
Como o isolamento do cGPU não oferece suporte à Unified Virtual Memory (UVM), não é possível chamar cudaMallocManaged() para alocar memória da GPU. Em vez disso, chame cudaMalloc(). Para obter mais informações, consulte a documentação da NVIDIA.
Pré-requisitos
Verifique se sua instância acelerada por GPU atende aos seguintes requisitos:
A família da instância deve ser uma das seguintes: gn7i, gn6i, gn6v, gn6e, gn5i, gn5, ebmgn7i, ebmgn6i, ebmgn7e, ebmgn6e .
O sistema operacional deve ser um dos seguintes: CentOS, Ubuntu ou Alibaba Cloud Linux.
Driver Tesla 418.87.01 ou posterior instalado.
Docker 19.03.5 ou posterior instalado.
Instale o cGPU
Recomendamos instalar e usar o cGPU no runtime Docker do ACK.
A instalação da versão 1.5.7 do cGPU pode causar um deadlock (em que processos executados simultaneamente bloqueiam uns aos outros) no driver de kernel do cGPU, o que pode levar a um Kernel Panic do Linux. Para evitar erros de kernel em novas cargas de trabalho, recomendamos instalar o cGPU 1.5.8 ou posterior, ou atualizar gradualmente as versões anteriores para a 1.5.8 ou superior.
-
Crie um cluster.
Para obter mais informações, consulte Criar um cluster gerenciado do ACK.
Na página Clusters, clique em nome do seu cluster. No painel de navegação à esquerda, clique em .
Na seção Basic capabilities, selecione Scheduling Policy Extension (Batch Task Scheduling, GPU Sharing, Topology-aware GPU Scheduling).
-
Na parte inferior da página, clique em Deploy Cloud-native AI Suite.
Após a instalação, o componente ack-ai-installer aparece na lista de componentes na página Cloud-native AI Suite.
Na página Cloud-native AI Suite, clique em Deploy.
Use o cGPU
Este tópico demonstra como dois containers em uma instância ecs.gn6i-c4g1.xlarge podem compartilhar uma única GPU.
Execute containers com cGPU
-
Execute os comandos a seguir para criar containers e definir a memória da GPU visível para cada container.
Neste exemplo, as variáveis de ambiente
ALIYUN_COM_GPU_MEM_CONTAINEReALIYUN_COM_GPU_MEM_DEVsão definidas para especificar a memória da GPU visível para o container e a memória total da GPU do dispositivo.-
gpu_test1: aloca 6 GiB de memória da GPU.
sudo docker run -d -t --gpus all --shm-size=1g --ulimit memlock=-1 --ulimit stack=67108864 --name gpu_test1 -v /mnt:/mnt -e ALIYUN_COM_GPU_MEM_CONTAINER=6 -e ALIYUN_COM_GPU_MEM_DEV=15 nvcr.io/nvidia/tensorflow:19.10-py3 -
gpu_test2: aloca 8 GiB de memória da GPU.
sudo docker run -d -t --gpus all --shm-size=1g --ulimit memlock=-1 --ulimit stack=67108864 --name gpu_test2 -v /mnt:/mnt -e ALIYUN_COM_GPU_MEM_CONTAINER=8 -e ALIYUN_COM_GPU_MEM_DEV=15 nvcr.io/nvidia/tensorflow:19.10-py3
NotaOs comandos usam a imagem de container TensorFlow
nvcr.io/nvidia/tensorflow:19.10-py3como exemplo. Substitua-a pela sua própria imagem de container. Para obter mais informações sobre como usar uma imagem do TensorFlow para construir um framework de deep learning TensorFlow, consulte Implantar um ambiente NGC para desenvolvimento de deep learning. -
-
Execute o comando a seguir para visualizar as informações da GPU do container, como a memória da GPU.
sudo docker exec -i gpu_test1 nvidia-smiPor exemplo, a memória da GPU visível para o container gpu_test1 é de 6.043 MiB, conforme mostrado na saída a seguir:
NVIDIA-SMI 440.33.01 Driver Version: 440.33.01 CUDA Version: 10.2 +-----------------------------------------------------------------------------+ | GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. | |=============================================================================| | 0 Tesla T4 On | 00000000:00:08.0 Off | 0 | | N/A 29C P8 9W / 70W | 0MiB / 6043MiB | 0% Default | +-----------------------------------------------------------------------------+ +-----------------------------------------------------------------------------+ | Processes: GPU Memory | | GPU PID Type Process name Usage | |=============================================================================| | No running processes found | +-----------------------------------------------------------------------------+
Visualize informações do cGPU com nós procfs
Quando o cGPU está em execução, ele gera e gerencia automaticamente vários nós do sistema de arquivos proc (procfs) no diretório /proc/cgpu_km. Use esses nós procfs para visualizar e configurar informações do cGPU.
-
Execute o comando a seguir para visualizar informações sobre os nós procfs.
ls /proc/cgpu_km/A seguinte saída é retornada:
0 default_memsize inst_ctl upgrade version -
Execute o comando a seguir para visualizar o conteúdo do diretório da GPU.
Este exemplo usa a GPU 0.
ls /proc/cgpu_km/0A seguinte saída é retornada:
012b2edccd7a 0852a381c0cf free_weight major max_inst policy prio_ratio -
Execute o comando a seguir para visualizar o conteúdo do diretório de um container.
Este exemplo usa o container
012b2edccd7a.ls /proc/cgpu_km/0/012b2edccd7aA seguinte saída é retornada:
highprio id meminfo memsize weight -
(Opcional) Execute os comandos a seguir para configurar o cGPU.
Use os nós procfs para executar comandos na instância acelerada por GPU, alternar a política de agendamento, modificar pesos e realizar outras operações. A tabela a seguir fornece exemplos de comandos.
Comando
Efeito
echo 2 > /proc/cgpu_km/0/policy
Alterna a política de agendamento para agendamento preemptivo baseado em peso.
cat /proc/cgpu_km/0/free_weight
Visualiza o peso disponível na GPU. Se
free_weight=0, um container recém-criado recebe peso 0. O container não consegue obter poder de computação da GPU.cat /proc/cgpu_km/0/$dockerid/weight
Visualiza o peso de um container especificado.
echo 4 > /proc/cgpu_km/0/$dockerid/weight
Modifica o peso do poder de computação para um container.
Visualize containers cGPU com cgpu-smi
Use o cgpu-smi para visualizar informações sobre containers cGPU, incluindo IDs de container, utilização da GPU, limites de poder de computação, memória da GPU usada e memória total da GPU alocada.
O cgpu-smi é um exemplo de monitoramento para cGPU. Ao implantar aplicativos no Kubernetes (k8s), use ou adapte a ferramenta cgpu-smi para integrações personalizadas.
| Alibaba Cloud cGPU1.0 cGPU Version: 1.0.2
+---+----------------+----------+----------------+-----------------------+
|GPU| pod | highprio | GPU-Util/Limit | GPU Memory Usage/Total|
+===+================+==========+================+=======================+
| 0| 7db8fff70a0d | 0 | 41/ 50 | 9459/11463 |
| 0| 91b1e19795ee | 0 | 30/ 50 | 9457/11463 |
+---+----------------+----------+----------------+-----------------------+
Atualize ou desinstale o cGPU
Atualize o cGPU
O cGPU suporta atualizações a frio e atualizações a quente.
-
Cold update
Para realizar uma atualização a frio quando o Docker não estiver usando o cGPU:
-
Pare todos os containers em execução:
sudo docker stop $(docker ps -a | awk '{ print $1}' | tail -n +2) -
Atualize o cGPU para a versão mais recente:
sudo sh upgrade.sh
-
-
Hot update
Se o Docker estiver usando o cGPU, realize uma atualização a quente do driver de kernel do cGPU. No entanto, este método de atualização está sujeito a restrições de versão. Entre em contato com a equipe de suporte pós-venda da Alibaba Cloud para obter assistência.
Desinstale o cGPU
Para desinstalar uma versão anterior do cGPU de um nó, consulte Atualizar a versão do cGPU do nó.
Exemplos de uso do cGPU
Agendamento de poder de computação
Quando o cGPU carrega o módulo cgpu_km, ele define fatias de tempo (em milissegundos) para cada GPU com base no número máximo de containers (max_inst). Essas fatias de tempo, referidas como Slice 1, Slice 2 e Slice N neste tópico, são usadas para alocar poder de computação da GPU aos containers. Os exemplos a seguir demonstram diferentes políticas de agendamento.
-
Agendamento de divisão justa (policy=0)
Ao criar containers, o cGPU aloca uma fatia de tempo para cada um. O agendador começa com a Slice 1, envia uma tarefa para a GPU física por uma fatia de tempo e, em seguida, alterna para a próxima fatia de tempo. Cada container recebe uma parte igual de poder de computação, que é
1/max_inst, conforme mostrado na figura a seguir. -
Agendamento preemptivo (policy=1)
Ao criar containers, o cGPU aloca fatias de tempo para eles. O agendador começa com a Slice 1. No entanto, se nenhum processo em um container estiver acessando a GPU, o agendador ignora a fatia de tempo desse container e passa para a próxima.
Exemplo:
Crie um único container, Docker 1, ao qual é alocada a Slice 1. Se você executar dois processos TensorFlow no Docker 1, o container poderá usar o poder de computação de toda a GPU física.
Em seguida, crie um segundo container, Docker 2, ao qual é alocada a Slice 2. Se nenhum processo no Docker 2 estiver acessando a GPU, o agendador ignora sua fatia de tempo (Slice 2).
-
Quando um processo no Docker 2 começa a acessar a GPU, tanto a Slice 1 quanto a Slice 2 são incluídas no ciclo de agendamento. O Docker 1 e o Docker 2 podem receber, cada um, até metade do poder de computação da GPU física, conforme mostrado na figura a seguir.
-
Agendamento preemptivo baseado em peso (policy=2)
Se você definir
ALIYUN_COM_GPU_SCHD_WEIGHTcom um valor maior que 1 ao criar um container, o cGPU usará automaticamente essa política. O cGPU divide o poder de computação da GPU física emmax_instpartes. SeALIYUN_COM_GPU_SCHD_WEIGHTfor maior que 1, o cGPU combina várias fatias de tempo em uma fatia maior para esse container.Configuração de exemplo:
Docker 1: ALIYUN_COM_GPU_SCHD_WEIGHT=m
Docker 2: ALIYUN_COM_GPU_SCHD_WEIGHT=n
Comportamento de agendamento:
Se apenas o Docker 1 estiver em execução, ele preempta o poder de computação de toda a GPU física.
-
Se o Docker 1 e o Docker 2 estiverem ambos em execução, eles recebem poder de computação em uma proporção teórica de m:n. Diferentemente do agendamento preemptivo, o Docker 2 consome n fatias de tempo mesmo que nenhum processo nele esteja usando a GPU.
NotaO desempenho difere quando a proporção m:n é definida como 2:1 versus 8:4. No caso 2:1, o número de trocas de fatias de tempo por segundo é quatro vezes maior do que no caso 8:4.
O agendamento preemptivo baseado em peso estabelece um limite máximo teórico para o poder de computação da GPU que um container pode usar. No entanto, para GPUs potentes como a NVIDIA V100, uma tarefa curta de computação pode terminar dentro de uma única fatia de tempo. Nesse cenário, se a proporção m:n for 8:4, a GPU fica ociosa durante as fatias de tempo restantes, tornando o limite ineficaz.
-
Agendamento fixo (policy=3)
Aloque uma porcentagem fixa de poder de computação especificando uma proporção de
ALIYUN_COM_GPU_SCHD_WEIGHTparamax_inst. -
Agendamento suave (policy=4)
Ao criar containers, o cGPU aloca fatias de tempo para eles. Esta política fornece isolamento mais fraco do que o agendamento preemptivo. Para obter mais informações, consulte Agendamento preemptivo (policy=1).
-
Agendamento nativo (policy=5)
Esta política isola apenas a memória da GPU e depende do método de agendamento nativo do driver da GPU NVIDIA.
As políticas de agendamento de poder de computação suportam todas as instâncias heterogêneas aceleradas por GPU da Alibaba Cloud e suas GPUs NVIDIA, incluindo Tesla P4, Tesla P100, Tesla T4, Tesla V100, Tesla A10, . Os testes a seguir usam dois containers que compartilham uma instância de GPU única com uma GPU Tesla A10. A proporção de poder de computação entre os containers é de 1:2, e a memória da GPU é dividida igualmente, com cada container recebendo 12 GB.
Os resultados dos testes de desempenho a seguir são de um ambiente de laboratório e servem apenas como referência.
-
Teste 1: Compara o desempenho de um modelo ResNet50 treinado no framework TensorFlow com precisão FP16 em diferentes valores de
batch_size. Os resultados são mostrados abaixo:Framework
Modelo
batch_size
Precisão
Imagens/seg (Docker 1)
Imagens/seg (Docker 2)
TensorFlow
ResNet50
16
FP16
151
307
TensorFlow
ResNet50
32
FP16
204
418
TensorFlow
ResNet50
64
FP16
247
503
TensorFlow
ResNet50
128
FP16
257
516

-
Teste 2: Compara o desempenho de um modelo ResNet50 treinado no framework TensorRT com precisão FP16 em diferentes valores de
batch_size. Os resultados são mostrados abaixo:Framework
Modelo
batch_size
Precisão
Imagens/seg (Docker 1)
Imagens/seg (Docker 2)
TensorRT
ResNet50
1
FP16
568,05
1132,08
TensorRT
ResNet50
2
FP16
940,36
1884,12
TensorRT
ResNet50
4
FP16
1304,03
2571,91
TensorRT
ResNet50
8
FP16
1586,87
3055,66
TensorRT
ResNet50
16
FP16
1783,91
3381,72
TensorRT
ResNet50
32
FP16
1989,28
3695,88
TensorRT
ResNet50
64
FP16
2105,81
3889,35
TensorRT
ResNet50
128
FP16
2205,25
3901,94

Particionamento de memória multi-GPU
Este exemplo mostra como particionar a memória em quatro GPUs, alocando 3 GB para a GPU 0, 4 GB para a GPU 1, 5 GB para a GPU 2 e 6 GB para a GPU 3. O código de exemplo é o seguinte:
docker run -d -t --runtime=nvidia --name gpu_test0123 --shm-size=1g --ulimit memlock=-1 --ulimit stack=67108864 -v /mnt:/mnt -e ALIYUN_COM_GPU_MEM_CONTAINER=3,4,5,6 -e ALIYUN_COM_GPU_MEM_DEV=23 -e NVIDIA_VISIBLE_DEVICES=0,1,2,3 nvcr.io/nvidia/tensorflow:21.03-tf1-py3
docker exec -i gpu_test0123 nvidia-smi
A saída do comando mostra os detalhes de memória das quatro GPUs.
NVIDIA-SMI 510.39 Driver Version: 510.39 CUDA Version: 11.6
-------------------------------+----------------------+----------------------+
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 A10 On | 00000000:61:00.0 Off | 0 |
0% 31C P8 15W / 150W | 0MiB / 3003MiB | 0% Default |
| | N/A |
+-------------------------------+----------------------+----------------------+
1 NVIDIA A10 On | 00000000:6B:00.0 Off | 0 |
0% 31C P8 16W / 150W | 0MiB / 4004MiB | 0% Default |
| | N/A |
+-------------------------------+----------------------+----------------------+
2 NVIDIA A10 On | 00000000:CA:00.0 Off | 0 |
0% 30C P8 15W / 150W | 0MiB / 5006MiB | 0% Default |
| | N/A |
+-------------------------------+----------------------+----------------------+
3 NVIDIA A10 On | 00000000:E3:00.0 Off | 0 |
0% 31C P8 16W / 150W | 0MiB / 6007MiB | 0% Default |
| | N/A |
+-------------------------------+----------------------+----------------------+
A tabela a seguir descreve o parâmetro ALIYUN_COM_GPU_MEM_CONTAINER para configurações multi-GPU.
|
Valor |
Descrição |
|
ALIYUN_COM_GPU_MEM_CONTAINER=3 |
Define a memória da GPU de todas as quatro GPUs para 3 GB. |
|
ALIYUN_COM_GPU_MEM_CONTAINER=3,1 |
Define a memória da GPU das quatro GPUs para 3 GB, 1 GB, 1 GB e 1 GB, respectivamente. |
|
ALIYUN_COM_GPU_MEM_CONTAINER=3,4,5,6 |
Define a memória da GPU das quatro GPUs para 3 GB, 4 GB, 5 GB e 6 GB, respectivamente. |
|
ALIYUN_COM_GPU_MEM_CONTAINER não especificado |
Desativa o cGPU. |
|
ALIYUN_COM_GPU_MEM_CONTAINER=0 |
|
|
ALIYUN_COM_GPU_MEM_CONTAINER=1,0,0 |