Observação:

Configurar um Sistema de Benchmarking de Inferência de LLM Simples com vLLM no Oracle Cloud Infrastructure Compute

Introdução

Compreender as características de desempenho de um sistema permite que você faça escolhas informadas sobre seus componentes e o que esperar deles. Neste tutorial, vamos configurar um sistema completo de benchmarking para inferência de modelo de linguagem grande (LLM) de IA. Usando isso, você pode executar vários experimentos avaliando a adequação de uma forma específica do Oracle Cloud Infrastructure (OCI) Compute para o LLM e os requisitos de desempenho em mente para comparar vários LLMs entre si.

Neste tutorial, usamos o popular servidor de inferência de código aberto vLLM, que suporta muitos LLMs de última geração e oferece otimizações de desempenho cruciais para atender com eficiência esses modelos e é capaz de lidar com milhares de solicitações simultâneas. Além disso, usamos o Ray LLMPerf para executar os benchmarks.

Observação: Este tutorial pressupõe que você tenha uma tenancy do OCI com uma cota de GPU. Para obter mais informações sobre cotas, consulte Cotas de Computação.

Objetivos

Pré-requisitos

Tarefa 1: Configurar a Rede

Nesta tarefa, configure sua VCN (Rede Virtual na Nuvem) para fornecer uma configuração funcional e segura para executar seus benchmarks. Neste exemplo, precisamos de uma VCN com uma sub-rede pública e uma privada. Você pode usar o assistente de configuração de VCN ou configurar manualmente todos os componentes, certificando-se de que as listas de segurança permitam o acesso SSH e que um gateway NAT seja designado à sub-rede privada.

Visão geral da arquitetura da solução que compreende uma sub-rede privada e pública, um bastion host e a VM de GPU em teste

Antes de provisionar instâncias do OCI Compute e continuar com a configuração do benchmark, é importante garantir que suas definições de rede estejam configuradas corretamente. Por padrão, a rede provisionada permite apenas tráfego essencial entre sub-redes. Para permitir o tráfego de rede necessário para o benchmarking, você precisará ajustar essas definições para permitir o tráfego HTTP entre as sub-redes pública e privada. Especificamente, adicione uma regra de entrada à lista de segurança da sub-rede privada que permite tráfego do bloco CIDR da VCN para a porta de destino 8000.

Tarefa 2: Provisionar Instâncias do OCI Compute

Nesta tarefa, provisione duas instâncias do OCI Compute para nossa configuração de benchmark. Uma delas é uma instância de máquina virtual (VM) somente para CPU que atua como bastion e a máquina cliente de benchmark, a outra é a instância equipada com GPU em teste.

  1. Provisione uma instância VM.Flex.E5 com oito OCPUs e o Oracle Linux 8. O cliente bastion/benchmark não requer uma GPU, pois só enviará solicitações ao modelo hospedado em uma máquina separada, daí a escolha de uma forma de CPU. Certifique-se de selecionar a sub-rede pública nos parâmetros de rede e não se esqueça de fazer upload da sua chave pública SSH (ou faça download da chave privada fornecida, se preferir).

  2. Provisione uma instância VM.GPU.A10.1. Para simplificar a configuração, provisione a instância usando uma imagem do Oracle Linux 8 que inclua drivers NVIDIA e a estrutura CUDA. Comece selecionando a forma desejada, navegue de volta para o menu de seleção de imagem e escolha a variante do Oracle Linux 8 com suporte de GPU integrado. Essa instância deve ser provisionada na sub-rede privada, o que significa que ela só pode ser acessada usando o bastion host. Certifique-se de configurar a chave SSH também.

Captura de tela da seleção da imagem do Oracle Linux 8 com suporte de GPU incorporado

Tarefa 3: Configurar o Cliente de Benchmark

Nesta tarefa, vamos instalar todos os componentes necessários para nossos benchmarks de desempenho e configurar o host GPU.

  1. Faça log-in no bastion com sua chave SSH e configure todos os requisitos para LLMPerf usando o comando a seguir.

    sudo dnf install epel-release -y
    sudo yum-config-manager --enable ol8_baseos_latest ol8_appstream ol8_addons ol8_developer_EPEL
    sudo dnf install git python3.11 python3.11-devel python3.11-pip -y
    
  2. Clone o repositório Ray LLMPerf, configure um Python venv e instale LLMPerf usando o comando a seguir.

    git clone https://github.com/ray-project/llmperf.git
    cd llmperf
    mkdir venv && python3.11 -mvenv venv && source venv/bin/activate
    
  3. Antes de instalar LLMPerf (e suas dependências do Python), edite o arquivo pyproject.toml e remova a cláusula de requisito do Python. A cláusula limita desnecessariamente a versão do Python a ser menor que 3.11.

    diff --git a/pyproject.toml b/pyproject.toml
    index 7687fb2..521a2a7 100644
    --- a/pyproject.toml
    +++ b/pyproject.toml
    @@ -8,7 +8,6 @@ version = "0.1.0"
     description = "A framework for load testing LLM APIs"
     authors = [{name="Avnish Narayan", email="avnish@anyscale.com"}]
     license = {text= "Apache-2.0"}
    -requires-python = ">=3.8, <3.11"
     dependencies = ["pydantic<2.5",
                     "ray",
                     "pytest>=6.0",
    
  4. Execute o comando pip install -e para finalizar a configuração.

Tarefa 4: Configurar o Destino do Benchmark

Nesta tarefa, configuraremos o próprio alvo de benchmark. Como já provisionamos o nó com os drivers necessários e o framework Compute Unified Device Architecture (CUDA), basta instalar o vLLM e suas dependências de python e implantar o modelo que queremos comparar.

Observação: A instância de computação de GPU provisionada reside em uma sub-rede privada. Portanto, para acessá-lo, primeiro você deve fazer log-in no bastion host e configurar a chave SSH privada escolhida para o destino de benchmark. Só então você poderá fazer log-in no destino de benchmark usando seu endereço IP privado.

  1. Instale os pacotes necessários, como a configuração inicial no bastion host. Além disso, atualize o firewall do host para permitir o tráfego de entrada na porta 8000 usando o comando a seguir.

    sudo dnf install epel-release -y
    sudo yum-config-manager --enable ol8_baseos_latest ol8_appstream ol8_addons ol8_developer_EPEL
    sudo dnf install git python3.11 python3.11-devel python3.11-pip -y
    sudo firewall-cmd --permanent --zone=public --add-port=8000/tcp
    sudo firewall-cmd --reload
    
  2. Execute o comando a seguir para instalar o vLLM e seus requisitos.

    mkdir venv
    python3.11 -mvenv venv && source venv/bin/activate
    pip install -U pip "bitsandbytes>=0.44.0" vllm gpustat mistral_common
    
  3. Estamos prontos para iniciar o vLLM com o modelo que gostaríamos de testar.

    export HF_TOKEN=<your huggingface token>
    export MODEL="meta-llama/Llama-3.2-3B-Instruct"
    ulimit -Sn 65536 # increase limits to avoid running out of files that can be opened
    vllm serve $MODEL --tokenizer-mode auto --config-format hf --load-format auto \
                      --enforce-eager --max-model-len 65536
    

    Observação: Precisamos reduzir o tamanho do contexto do modelo para caber na memória GPU A10. Reduzimos o tamanho do contexto do tamanho padrão de tokens 128k para tokens 64k. Após o carregamento, o modelo vLLM deve começar a gerar suas estatísticas de inferência em intervalos regulares.

    INFO 12-09 15:46:36 metrics.py:449] Avg prompt throughput: 0.0 tokens/s, Avg generation throughput: 0.0 tokens/s, Running: 0 reqs, Swapped: 0 reqs, Pending: 0 reqs, GPU KV cache usage: 0.0%, CPU KV cache usage: 0.0%.
    
  4. Permitimos que o servidor continue em execução em segundo plano enquanto mudamos para outro terminal, onde agora testaremos e avaliaremos nossa configuração. Um teste simples pode ser executado com curl da seguinte forma.

    export HOST="<the ip address of the benchmark machine"
    export MODEL="meta-llama/Llama-3.2-3B-Instruct"
    curl --location "http://${HOST}:8000/v1/chat/completions"     --header 'Content-Type: application/json'     --header 'Authorization: Bearer token'     --data '{
            "model": "'"$MODEL"'",
            "messages": [
              {
                "role": "user",
                "content": "What is the question to the answer to the ultimate question of life, the universe, and everything. You may give a humorous response."
              }
            ]
        }' -s | jq
    

    A saída será:

    {
      "id": "chatcmpl-f11306f943604d41bad84be1dadd9da6",
      "object": "chat.completion",
      "created": 1733997638,
      "model": "meta-llama/Llama-3.2-3B-Instruct",
      "choices": [
        {
          "index": 0,
          "message": {
            "role": "assistant",
            "content": "You want to know the ultimate question to the answer of 42?\n\nWell, after years of intense research and contemplation, I've discovered that the answer is actually a giant, cosmic joke. The question is: \"What's for lunch?\"",
            "tool_calls": []
          },
          "logprobs": null,
          "finish_reason": "stop",
          "stop_reason": null
        }
      ],
      "usage": {
        "prompt_tokens": 62,
        "total_tokens": 112,
        "completion_tokens": 50,
        "prompt_tokens_details": null
      },
      "prompt_logprobs": null
    }
    

Tarefa 5: Executar o Benchmark

Agora, estamos prontos para executar nosso benchmark. Dado um cenário de aplicativo específico com um modelo de linguagem grande escolhido, gostaríamos de entender no sistema de destino quais são as características de desempenho da execução de solicitações de inferência simultâneas.

Vamos comparar o seguinte cenário:

PARAMETER VALOR
MODELO Instrução Meta LLaMa 3.2 3B
CASO DE USO bate-papo
TOKENS DE ENTRADA N(200, 40)
TOKENS DE SAÍDA N(100, 10)
SOLICITAÇÕES CONCORRENTES 1 - 32
  1. Crie o script a seguir chamado llm_benchmark.sh no cliente de benchmark (host bastion) dentro do diretório home.

    #!/usr/bin/env bash
    
    set -xe
    
    # Use vLLM OpenAPI endpoint
    export OPENAI_API_BASE="http://<benchmark host>:8000/v1"
    # API key is not in use, but needs to be set for llmbench
    export OPENAI_API_KEY="none"
    
    model="meta-llama/Llama-3.2-3B-Instruct"
    
    modelname="${model##*/}"
    mkdir "$modelname"
    
    concurrent_requests=(1 2 4 8 16 32)
    
    pushd llmperf
    
    source venv/bin/activate
    
    for cr in "${concurrent_requests[@]}"
    do
        python3 token_benchmark_ray.py --model $model \
            --mean-input-tokens 200 --stddev-input-tokens 40 \
            --mean-output-tokens 100 --stddev-output-tokens 10 \
            --max-num-completed-requests $((cr * 100)) --num-concurrent-requests $cr \
            --metadata "use_case=chatbot" \
            --timeout 1800 --results-dir "../$modelname/result_outputs_chat_creq_$cr" --llm-api openai
    done
    popd
    

    Este script permitirá que você execute automaticamente uma série de benchmarks com llmperf com número crescente de solicitações simultâneas (começando em 1 e dobrando sucessivamente até 32). Como você pode ver nos argumentos passados para o script token_benchmark_ray.py, estamos definindo entradas e saídas de token conforme definido na tabela acima.

  2. Execute seu script de benchmark usando o comando a seguir.

    bash -x llm_benchmark.sh
    

Uma vez feito, você encontrará um novo diretório chamado Llama-3.2-3B-Instruct em seu diretório home, onde todos os resultados do experimento serão armazenados no formato JSON, que você pode baixar e pós-processar usando sua ferramenta de análise de dados favorita.

Observação: Uma maneira fácil de transformar seus benchmarks em um gráfico é extrair os números que mais lhe interessam usando um pequeno script shell e jq no formato .csv, que pode ser facilmente copiado e colado no Excel.

echo "concurrent_requests,token_throughput"
for i in *; do
    cat $i/*_summary.json | jq -r '[.num_concurrent_requests, .results_request_output_throughput_token_per_s_mean] | join(",")'
done;

Confirmações

Mais Recursos de Aprendizagem

Explore outros laboratórios em docs.oracle.com/learn ou acesse mais conteúdo de aprendizado gratuito no canal Oracle Learning YouTube. Além disso, visite education.oracle.com/learning-explorer para se tornar um Oracle Learning Explorer.

Para obter a documentação do produto, visite o Oracle Help Center.