Execução de dois contêineres LLM simultaneamente#

Nesta seção, descrevemos a configuração para executar dois modelos de linguagem simultaneamente em um único servidor com várias GPUs.

Quando isso é necessário#

Executar dois contêineres LLM é útil quando:

  • Você tem várias GPUs e deseja usá-las para diferentes modelos
  • É necessário executar diferentes modelos ao mesmo tempo (por exemplo, um para chat, outro para tarefas especializadas)
  • É necessário distribuir a carga entre vários modelos

Requisitos#

  • Servidor com pelo menos 2 GPUs NVIDIA
  • Cada GPU deve ter memória suficiente para o modelo escolhido
  • Docker e Docker Compose instalados
  • NVIDIA Container Toolkit instalado

Configuração#

Passo 1: Verificando GPUs disponíveis#

Certifique-se de que você tem pelo menos 2 GPUs:

nvidia-smi

Resultado esperado: Você deve ver pelo menos 2 GPUs na lista.

Passo 2: Descomentando o segundo contêiner LLM#

Abra o arquivo docker-compose.yml e encontre o bloco comentado aiserver-llm-server2 (aproximadamente linhas 103-142).

Descomente todo o bloco, removendo os caracteres # no início de cada linha:

# Era:
# aiserver-llm-server2:
#   container_name: aiserver-llm-server2
#   image: aiserver-llm-server:latest
#   ...

# Agora:
aiserver-llm-server2:
  container_name: aiserver-llm-server2
  image: aiserver-llm-server:latest
  ...

Passo 3: Configurando portas#

Certifique-se de que as portas não estão em conflito:

  • aiserver-llm-server (primeiro contêiner): porta 3003:8000
  • aiserver-llm-server2 (segundo contêiner): a porta deve ser diferente, por exemplo 3006:8000 ou 3007:8000

No bloco comentado, verifique a linha:

ports:
  - 3006:8000  # ou outra porta livre

Passo 4: Configurando GPU para cada contêiner#

É importante configurar qual GPU será usada por cada contêiner.

Para o primeiro contêiner (aiserver-llm-server)

Normalmente usa a GPU 0 (por padrão). Verifique as variáveis de ambiente no arquivo .env ou no próprio docker-compose.yml:

environment:
  LLM_CUDA_VISIBLE_DEVICES: 0  # ou não especificar, então será usada a GPU 0

Para o segundo contêiner (aiserver-llm-server2)

No bloco descomentado, encontre a linha:

environment:
  LLM_CUDA_VISIBLE_DEVICES: 1  # Usa a GPU 1

Certifique-se de que o valor corresponde ao número da segunda GPU (geralmente 1 para a segunda GPU).

Passo 5: Configurando modelos#

Certifique-se de que cada modelo está configurado corretamente:

Primeiro contêiner (aiserver-llm-server)

Usa as configurações do arquivo .env ou valores padrão. Verifique a variável:

LLM_COMPLETION_MODEL_NAME=/model-store/nome-do-modelo-1

Segundo contêiner (aiserver-llm-server2)

No bloco descomentado, encontre a linha:

environment:
  LLM_COMPLETION_MODEL_NAME: "/model-store/Qwen3-30B-A3B-AWQ"

Altere para o modelo desejado, se necessário.

Passo 6: Verificando a configuração#

Antes de iniciar, verifique a configuração:

# Verifique a sintaxe do arquivo docker-compose
docker compose -f docker-compose.yml config

# Verifique se as portas não estão ocupadas
netstat -tuln | grep -E '3003|3006'

Passo 7: Iniciando os contêineres#

# Pare os contêineres atuais (se estiverem em execução)
docker compose -f docker-compose.yml down

# Inicie todos os contêineres, incluindo o segundo servidor LLM
docker compose -f docker-compose.yml up -d

# Verifique se ambos os contêineres estão em execução
docker compose -f docker-compose.yml ps | grep llm-server

Resultado esperado: Você deve ver dois contêineres:

  • aiserver-llm-server (porta 3003)
  • aiserver-llm-server2 (porta 3006)

Passo 8: Verificando o funcionamento#

# Verifique os logs do primeiro contêiner
docker logs aiserver-llm-server

# Verifique os logs do segundo contêiner
docker logs aiserver-llm-server2

# Verifique o uso da GPU
nvidia-smi

Resultado esperado:

  • Ambos os contêineres devem iniciar com sucesso
  • No nvidia-smi, devem ser visíveis processos em diferentes GPUs
  • Os logs não devem conter erros críticos

Configuração de variáveis de ambiente#

Se precisar alterar as configurações do segundo contêiner, edite o bloco environment no docker-compose.yml:

aiserver-llm-server2:
  environment:
    LLM_COMPLETION_MODEL_NAME: "/model-store/seu-modelo"
    LLM_CUDA_VISIBLE_DEVICES: 1  # Número da GPU (0, 1, 2, etc.)
    LLM_TENSOR_PARALLEL_SIZE: "1"
    LLM_MAX_MODEL_LEN: "16000"
    LLM_GPU_MEMORY_UTILIZATION: "0.85"
    # ... outras configurações

Possíveis problemas#

Contêiner não inicia#

Problema: O segundo contêiner não inicia ou falha com erro.

Solução:

  1. Verifique os logs: docker logs aiserver-llm-server2
  2. Certifique-se de que a GPU está disponível: nvidia-smi
  3. Verifique se a porta está livre: netstat -tuln | grep 3006
  4. Verifique se o modelo existe: ls -la llm-server/models/

Conflito de portas#

Problema: Erro "port is already allocated".

Solução:

  • Altere a porta do segundo contêiner para uma livre (por exemplo, 3007:8000)
  • Ou pare o serviço que está ocupando a porta

Memória GPU insuficiente#

Problema: O modelo não carrega, erros de memória.

Solução:

  • Reduza LLM_GPU_MEMORY_UTILIZATION (por exemplo, para 0.7)
  • Use modelos menores
  • Libere memória na GPU parando outros processos

Ambos os contêineres usam uma GPU#

Problema: Ambos os contêineres usam a GPU 0 em vez de GPUs diferentes.

Solução:

  • Certifique-se de que LLM_CUDA_VISIBLE_DEVICES está configurada corretamente para cada contêiner
  • Verifique se a variável não está sendo redefinida no arquivo .env
  • Reinicie os contêineres após alterar as configurações

Exemplo de configuração completa#

Exemplo de configuração de dois contêineres no docker-compose.yml:

aiserver-llm-server:
  container_name: aiserver-llm-server
  image: aiserver-llm-server:latest
  restart: always
  env_file:
    - .env
  ports:
    - 3003:8000
  environment:
    LLM_CUDA_VISIBLE_DEVICES: 0  # GPU 0
  deploy:
    resources:
      reservations:
        devices:
          - driver: nvidia
            count: all
            capabilities: [ gpu ]
  volumes:
    - "./llm-server/models:/model-store"
  networks:
    - llm-net

aiserver-llm-server2:
  container_name: aiserver-llm-server2
  image: aiserver-llm-server:latest
  restart: always
  ports:
    - 3006:8000
  environment:
    LLM_COMPLETION_MODEL_NAME: "/model-store/Qwen3-30B-A3B-AWQ"
    LLM_CUDA_VISIBLE_DEVICES: 1  # GPU 1
    LLM_TENSOR_PARALLEL_SIZE: "1"
    LLM_MAX_MODEL_LEN: "16000"
    LLM_GPU_MEMORY_UTILIZATION: "0.85"
  deploy:
    resources:
      reservations:
        devices:
          - driver: nvidia
            count: all
            capabilities: [ gpu ]
  volumes:
    - "./llm-server/models:/model-store"
  networks:
    - llm-net

Configurações adicionais#

Usando modelos diferentes#

Você pode executar modelos diferentes em cada contêiner:

# Primeiro contêiner - modelo para chat
LLM_COMPLETION_MODEL_NAME: "/model-store/Llama-3-8B"

# Segundo contêiner - modelo para código
LLM_COMPLETION_MODEL_NAME: "/model-store/Qwen3-30B-A3B-AWQ"

Configuração de memória#

Se você tiver GPUs com diferentes quantidades de memória, configure o uso de memória para cada contêiner:

# Para GPU com menor memória
LLM_GPU_MEMORY_UTILIZATION: "0.7"

# Para GPU com maior memória
LLM_GPU_MEMORY_UTILIZATION: "0.9"

Monitoramento#

Para monitorar o funcionamento de ambos os contêineres:

# Status dos contêineres
docker compose -f docker-compose.yml ps

# Uso de recursos
docker stats aiserver-llm-server aiserver-llm-server2

# Uso da GPU
watch -n 1 nvidia-smi

Resultado esperado: Ambos os contêineres devem funcionar de forma estável, utilizando GPUs diferentes.