Menyajikan LLM seperti DeepSeek-R1 671B atau Llama 3.1 405B di bare metal

Distributed Cloud khusus software untuk bare metal memungkinkan Anda menyajikan model bahasa besar (LLM) seperti DeepSeek-R1 671B atau Llama 3.1 405B di beberapa node GPU. Dalam dokumen ini, Anda akan menggunakan teknologi open source portabel, seperti Kubernetes, vLLM, dan API LeaderWorkerSet (LWS), untuk men-deploy dan menyajikan workload AI/ML di cluster bare metal.

Latar belakang

Bagian ini menjelaskan teknologi utama yang digunakan dalam panduan ini, termasuk dua LLM yang digunakan sebagai contoh dalam panduan ini: DeepSeek-R1 dan Llama 3.1 405B.

DeepSeek-R1

DeepSeek-R1, model bahasa besar dengan 671 miliar parameter dari DeepSeek, dirancang untuk inferensi logis, penalaran matematis, dan pemecahan masalah real-time dalam berbagai tugas berbasis teks. Google Distributed Cloud menangani permintaan komputasi DeepSeek-R1, mendukung kemampuannya dengan resource yang skalabel, komputasi terdistribusi, dan jaringan yang efisien.

Untuk mempelajari lebih lanjut, lihat dokumentasi DeepSeek.

Llama 3.1 405B

Llama 3.1 405B adalah model bahasa besar dari Meta yang dirancang untuk berbagai tugas natural language processing, termasuk pembuatan teks, terjemahan, dan question answering. Google Distributed Cloud menawarkan infrastruktur tangguh yang diperlukan untuk mendukung kebutuhan pelatihan dan inferensi terdistribusi untuk model berskala ini.

Untuk mempelajari lebih lanjut, lihat dokumentasi Llama.

Layanan Kubernetes terkelola Google Distributed Cloud

Google Distributed Cloud menawarkan berbagai layanan, termasuk software Distributed Cloud khusus untuk bare metal, yang sangat cocok untuk men-deploy dan mengelola workload AI/ML di pusat data Anda sendiri. Google Distributed Cloud adalah layanan Kubernetes terkelola yang menyederhanakan deployment, penskalaan, dan pengelolaan aplikasi dalam container. Google Distributed Cloud menyediakan infrastruktur yang diperlukan, termasuk resource yang skalabel, komputasi terdistribusi, dan jaringan yang efisien, untuk menangani permintaan komputasi LLM.

Untuk mempelajari lebih lanjut konsep utama Kubernetes, lihat Mulai mempelajari Kubernetes. Untuk mempelajari lebih lanjut Google Distributed Cloud dan cara Google Distributed Cloud membantu Anda menskalakan, mengotomatiskan, dan mengelola Kubernetes, lihat Ringkasan Distributed Cloud khusus software untuk bare metal.

GPU

Unit pemrosesan grafis (GPU) memungkinkan Anda mempercepat workload tertentu, seperti machine learning dan pemrosesan data. Google Distributed Cloud mendukung node yang dilengkapi dengan GPU canggih ini, sehingga Anda dapat mengonfigurasi cluster untuk performa optimal dalam tugas machine learning dan pemrosesan data. Google Distributed Cloud menyediakan berbagai opsi jenis mesin untuk konfigurasi node, termasuk jenis mesin dengan GPU NVIDIA H100, L4, dan A100.

Untuk mempelajari lebih lanjut, lihat Menginstal atau meng-uninstal Operator GPU NVIDIA yang dipaketkan atau Menyiapkan dan menggunakan GPU NVIDIA.

LeaderWorkerSet (LWS)

LeaderWorkerSet (LWS) adalah API deployment Kubernetes yang menangani pola deployment umum workload inferensi multi-node AI/ML. Penyajian multi-node memanfaatkan beberapa Pod, yang masing-masing berpotensi berjalan di node yang berbeda, untuk menangani workload inferensi terdistribusi. LWS memungkinkan beberapa Pod diperlakukan sebagai grup, sehingga menyederhanakan pengelolaan penyajian model terdistribusi.

vLLM dan inferensi multi-host

Saat menyajikan LLM yang intensif secara komputasi, sebaiknya gunakan vLLM dan jalankan workload di seluruh GPU.

vLLM adalah framework penyajian LLM open source yang sangat dioptimalkan dan dapat meningkatkan throughput penyajian di GPU, dengan fitur seperti berikut:

  • Implementasi transformer yang dioptimalkan dengan PagedAttention

  • Pengelompokan berkelanjutan untuk meningkatkan throughput inferensi secara keseluruhan

  • Penyajian terdistribusi di beberapa GPU

Dengan LLM yang sangat intensif secara komputasi dan tidak dapat dimuat ke dalam satu node GPU, Anda dapat menggunakan beberapa node GPU untuk menyajikan model. vLLM mendukung menjalankan workload di seluruh GPU dengan dua strategi:

  • Paralelisme tensor membagi perkalian matriks di lapisan transformer ke beberapa GPU. Namun, strategi ini memerlukan jaringan yang cepat karena komunikasi yang diperlukan antara GPU, sehingga kurang cocok untuk menjalankan workload di seluruh node.

  • Paralelisme pipeline membagi model berdasarkan lapisan, atau secara vertikal. Strategi ini tidak memerlukan komunikasi yang konstan antar-GPU, sehingga menjadi opsi yang lebih baik saat menjalankan model di seluruh node.

Anda dapat menggunakan kedua strategi tersebut dalam inferensi multi-node. Misalnya, saat menggunakan dua node dengan masing-masing delapan GPU H100, Anda dapat menggunakan kedua strategi:

  • Paralelisme pipeline dua arah untuk melakukan sharding model di dua node

  • Paralelisme tensor delapan arah untuk membagi model di delapan GPU pada setiap node

Untuk mempelajari lebih lanjut, lihat dokumentasi vLLM.

Tujuan

  1. Siapkan lingkungan Anda dengan cluster Google Distributed Cloud dalam mode Autopilot atau Standard.

  2. Deploy vLLM di beberapa node dalam cluster Anda.

  3. Gunakan vLLM untuk menyajikan model melalui curl.

Sebelum memulai

Mendapatkan akses ke model

Anda dapat menggunakan model Llama 3.1 405B atau DeepSeek-R1.

DeepSeek-R1

Membuat token akses

Jika Anda belum memilikinya, buat token Hugging Face baru:

  1. Klik Your Profile > Settings > Access Tokens.

  2. Pilih New Token.

  3. Tentukan Nama sesuai dengan pilihan Anda, dan berikan Peran minimal Read.

  4. Pilih Buat token.

Llama 3.1 405B

Membuat token akses

Jika Anda belum memilikinya, buat token Hugging Face baru:

  1. Klik Your Profile > Settings > Access Tokens.

  2. Pilih New Token.

  3. Tentukan Nama sesuai dengan pilihan Anda, dan berikan Peran minimal Read.

  4. Pilih Buat token.

Menyiapkan lingkungan

Untuk menyiapkan lingkungan Anda, ikuti langkah-langkah berikut:

  1. Tetapkan parameter berikut di workstation admin:

    gcloud config set project PROJECT_ID
    export PROJECT_ID=$(gcloud config get project)
    export HF_TOKEN=HUGGING_FACE_TOKEN
    export IMAGE_NAME= gcr.io/PROJECT_ID/vllm-multihost/vllm-multihost:latest
    

    Ganti nilai berikut:

    • PROJECT_ID: project ID yang terkait dengan cluster Anda.

    • HUGGING_FACE_TOKEN: token hugging face yang dihasilkan dari bagian Mendapatkan akses ke model sebelumnya.

Membuat Secret Kubernetes untuk kredensial Hugging Face

Buat Secret Kubernetes yang berisi token Hugging Face menggunakan perintah berikut:

kubectl create secret generic hf-secret \
    --kubeconfig KUBECONFIG \
    --from-literal=hf_api_token=${HF_TOKEN} \
    --dry-run=client -o yaml | kubectl apply -f -

Ganti KUBECONFIG dengan jalur file kubeconfig untuk cluster tempat Anda ingin menghosting LLM.

Menginstal LeaderWorkerSet

Untuk menginstal LWS, jalankan perintah berikut:

kubectl apply --server-side \
    --kubeconfig KUBECONFIG \
    -f https://github.com/kubernetes-sigs/lws/releases/latest/download/manifests.yaml

Validasi bahwa pengontrol LeaderWorkerSet berjalan di namespace lws-system, menggunakan perintah berikut:

kubectl get pod -n lws-system --kubeconfig KUBECONFIG

Outputnya mirip dengan hal berikut ini:

NAME                                      READY   STATUS    RESTARTS   AGE
lws-controller-manager-5c4ff67cbd-9jsfc   2/2     Running   0          6d23h

Men-deploy Server Model vLLM

Untuk men-deploy server model vLLM, ikuti langkah-langkah berikut:

  1. Buat dan terapkan manifes, bergantung pada LLM yang ingin Anda deploy.

    DeepSeek-R1

    1. Buat manifes YAML, vllm-deepseek-r1-A3.yaml, untuk server model vLLM:

      apiVersion: leaderworkerset.x-k8s.io/v1
      kind: LeaderWorkerSet
      metadata:
        name: vllm
      spec:
        replicas: 1
        leaderWorkerTemplate:
          size: 2
          restartPolicy: RecreateGroupOnPodRestart
          leaderTemplate:
            metadata:
              labels:
                role: leader
            spec:
              nodeSelector:
                cloud.google.com/gke-accelerator: nvidia-h100-80gb
              containers:
                - name: vllm-leader
                  image: vllm/vllm-openai:v0.8.5
                  env:
                    - name: HUGGING_FACE_HUB_TOKEN
                      valueFrom:
                        secretKeyRef:
                          name: hf-secret
                          key: hf_api_token
                  command:
                    - sh
                    - -c
                    - "bash /vllm-workspace/examples/online_serving/multi-node-serving.sh leader --ray_cluster_size=$(LWS_GROUP_SIZE);
                      python3 -m vllm.entrypoints.openai.api_server --port 8080 --model deepseek-ai/DeepSeek-R1 --tensor-parallel-size 8 --pipeline-parallel-size 2 --trust-remote-code --max-model-len 4096"
                  resources:
                    limits:
                      nvidia.com/gpu: "8"
                  ports:
                    - containerPort: 8080
                  readinessProbe:
                    tcpSocket:
                      port: 8080
                    initialDelaySeconds: 15
                    periodSeconds: 10
                  volumeMounts:
                    - mountPath: /dev/shm
                      name: dshm
              volumes:
              - name: dshm
                emptyDir:
                  medium: Memory
                  sizeLimit: 15Gi
          workerTemplate:
            spec:
              containers:
                - name: vllm-worker
                  image: vllm/vllm-openai:v0.8.5
                  command:
                    - sh
                    - -c
                    - "bash /vllm-workspace/examples/online_serving/multi-node-serving.sh worker --ray_address=$(LWS_LEADER_ADDRESS)"
                  resources:
                    limits:
                      nvidia.com/gpu: "8"
                  env:
                    - name: HUGGING_FACE_HUB_TOKEN
                      valueFrom:
                        secretKeyRef:
                          name: hf-secret
                          key: hf_api_token
                  volumeMounts:
                    - mountPath: /dev/shm
                      name: dshm
              volumes:
              - name: dshm
                emptyDir:
                  medium: Memory
                  sizeLimit: 15Gi
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: vllm-leader
      spec:
        ports:
          - name: http
            port: 8080
            protocol: TCP
            targetPort: 8080
        selector:
          leaderworkerset.sigs.k8s.io/name: vllm
          role: leader
        type: ClusterIP
      
    2. Terapkan manifes dengan menjalankan perintah berikut:

      kubectl apply -f vllm-deepseek-r1-A3.yaml \
          --kubeconfig KUBECONFIG
      

    Llama 3.1 405B

    1. Buat manifes YAML, vllm-llama3-405b-A3.yaml, untuk server model vLLM:

      apiVersion: leaderworkerset.x-k8s.io/v1
      kind: LeaderWorkerSet
      metadata:
        name: vllm
      spec:
        replicas: 1
        leaderWorkerTemplate:
          size: 2
          restartPolicy: RecreateGroupOnPodRestart
          leaderTemplate:
            metadata:
              labels:
                role: leader
            spec:
              nodeSelector:
                cloud.google.com/gke-accelerator: nvidia-h100-80gb
              containers:
                - name: vllm-leader
                  image: vllm/vllm-openai:v0.8.5
                  env:
                    - name: HUGGING_FACE_HUB_TOKEN
                      valueFrom:
                        secretKeyRef:
                          name: hf-secret
                          key: hf_api_token
                  command:
                    - sh
                    - -c
                    - "bash /vllm-workspace/examples/online_serving/multi-node-serving.sh leader --ray_cluster_size=$(LWS_GROUP_SIZE);
                      python3 -m vllm.entrypoints.openai.api_server --port 8080 --model meta-llama/Meta-Llama-3.1-405B-Instruct --tensor-parallel-size 8 --pipeline-parallel-size 2"
                  resources:
                    limits:
                      nvidia.com/gpu: "8"
                  ports:
                    - containerPort: 8080
                  readinessProbe:
                    tcpSocket:
                      port: 8080
                    initialDelaySeconds: 15
                    periodSeconds: 10
                  volumeMounts:
                    - mountPath: /dev/shm
                      name: dshm
              volumes:
              - name: dshm
                emptyDir:
                  medium: Memory
                  sizeLimit: 15Gi
          workerTemplate:
            spec:
              containers:
                - name: vllm-worker
                  image: vllm/vllm-openai:v0.8.5
                  command:
                    - sh
                    - -c
                    - "bash /vllm-workspace/examples/online_serving/multi-node-serving.sh worker --ray_address=$(LWS_LEADER_ADDRESS)"
                  resources:
                    limits:
                      nvidia.com/gpu: "8"
                  env:
                    - name: HUGGING_FACE_HUB_TOKEN
                      valueFrom:
                        secretKeyRef:
                          name: hf-secret
                          key: hf_api_token
                  volumeMounts:
                    - mountPath: /dev/shm
                      name: dshm
              volumes:
              - name: dshm
                emptyDir:
                  medium: Memory
                  sizeLimit: 15Gi
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: vllm-leader
      spec:
        ports:
          - name: http
            port: 8080
            protocol: TCP
            targetPort: 8080
        selector:
          leaderworkerset.sigs.k8s.io/name: vllm
          role: leader
        type: ClusterIP
      
    2. Terapkan manifes dengan menjalankan perintah berikut:

      kubectl apply -f vllm-llama3-405b-A3.yaml \
          --kubeconfig KUBECONFIG
      
  2. Lihat log dari server model yang sedang berjalan dengan perintah berikut:

    kubectl logs vllm-0 -c vllm-leader \
        --kubeconfig KUBECONFIG
    

    Output-nya akan terlihat seperti berikut:

    INFO 08-09 21:01:34 api_server.py:297] Route: /detokenize, Methods: POST
    INFO 08-09 21:01:34 api_server.py:297] Route: /v1/models, Methods: GET
    INFO 08-09 21:01:34 api_server.py:297] Route: /version, Methods: GET
    INFO 08-09 21:01:34 api_server.py:297] Route: /v1/chat/completions, Methods: POST
    INFO 08-09 21:01:34 api_server.py:297] Route: /v1/completions, Methods: POST
    INFO 08-09 21:01:34 api_server.py:297] Route: /v1/embeddings, Methods: POST
    INFO:     Started server process [7428]
    INFO:     Waiting for application startup.
    INFO:     Application startup complete.
    INFO:     Uvicorn running on http://0.0.0.0:8080 (Press CTRL+C to quit)
    

Menyajikan model

Siapkan penerusan port ke model dengan menjalankan perintah berikut:

kubectl port-forward svc/vllm-leader 8080:8080 \
    --kubeconfig KUBECONFIG

Berinteraksi dengan model menggunakan curl

Untuk berinteraksi dengan model menggunakan curl, ikuti petunjuk berikut:

DeepSeek-R1

Di terminal baru, kirim permintaan ke server:

curl http://localhost:8080/v1/completions \
-H "Content-Type: application/json" \
-d '{
    "model": "deepseek-ai/DeepSeek-R1",
    "prompt": "I have four boxes. I put the red box on the bottom and put the blue box on top. Then I put the yellow box on top the blue. Then I take the blue box out and put it on top. And finally I put the green box on the top. Give me the final order of the boxes from bottom to top. Show your reasoning but be brief",
    "max_tokens": 1024,
    "temperature": 0
}'

Outputnya akan mirip dengan berikut ini:

{
  "id": "cmpl-f2222b5589d947419f59f6e9fe24c5bd",
  "object": "text_completion",
  "created": 1738269669,
  "model": "deepseek-ai/DeepSeek-R1",
  "choices": [
    {
      "index": 0,
      "text": ".\n\nOkay, let's see. The user has four boxes and is moving them around. Let me try to visualize each step. \n\nFirst, the red box is placed on the bottom. So the stack starts with red. Then the blue box is put on top of red. Now the order is red (bottom), blue. Next, the yellow box is added on top of blue. So now it's red, blue, yellow. \n\nThen the user takes the blue box out. Wait, blue is in the middle. If they remove blue, the stack would be red and yellow. But where do they put the blue box? The instruction says to put it on top. So after removing blue, the stack is red, yellow. Then blue is placed on top, making it red, yellow, blue. \n\nFinally, the green box is added on the top. So the final order should be red (bottom), yellow, blue, green. Let me double-check each step to make sure I didn't mix up any steps. Starting with red, then blue, then yellow. Remove blue from the middle, so yellow is now on top of red. Then place blue on top of that, so red, yellow, blue. Then green on top. Yes, that seems right. The key step is removing the blue box from the middle, which leaves yellow on red, then blue goes back on top, followed by green. So the final order from bottom to top is red, yellow, blue, green.\n\n**Final Answer**\nThe final order from bottom to top is \\boxed{red}, \\boxed{yellow}, \\boxed{blue}, \\boxed{green}.\n</think>\n\n1. Start with the red box at the bottom.\n2. Place the blue box on top of the red box. Order: red (bottom), blue.\n3. Place the yellow box on top of the blue box. Order: red, blue, yellow.\n4. Remove the blue box (from the middle) and place it on top. Order: red, yellow, blue.\n5. Place the green box on top. Final order: red, yellow, blue, green.\n\n\\boxed{red}, \\boxed{yellow}, \\boxed{blue}, \\boxed{green}",
      "logprobs": null,
      "finish_reason": "stop",
      "stop_reason": null,
      "prompt_logprobs": null
    }
  ],
  "usage": {
    "prompt_tokens": 76,
    "total_tokens": 544,
    "completion_tokens": 468,
    "prompt_tokens_details": null
  }
}

Llama 3.1 405B

Di terminal baru, kirim permintaan ke server:

curl http://localhost:8080/v1/completions \
-H "Content-Type: application/json" \
-d '{
    "model": "meta-llama/Meta-Llama-3.1-405B-Instruct",
    "prompt": "San Francisco is a",
    "max_tokens": 7,
    "temperature": 0
}'

Outputnya akan mirip dengan berikut ini:

{"id":"cmpl-0a2310f30ac3454aa7f2c5bb6a292e6c",
"object":"text_completion","created":1723238375,"model":"meta-llama/Meta-Llama-3.1-405B-Instruct","choices":[{"index":0,"text":" top destination for foodies, with","logprobs":null,"finish_reason":"length","stop_reason":null}],"usage":{"prompt_tokens":5,"total_tokens":12,"completion_tokens":7}}

Langkah berikutnya