Розгортання DeepSeek з vLLM на кластері AWS EKS

pic

DeepSeek

DeepSeek нещодавно оголосив про свою нову модель DeepSeek-R1, яка перевершує різноманітні передові моделі, що є на ринку, як ми можемо побачити нижче.

pic

Як видно з діаграми вище, DeepSeek-R1 перевершує модель OpenAI-o1–1217, тоді як модель DeepSeek-R1–32B перевершує OpenAI-o1-mini за різними показниками, такими як AIME 2024, Codeforces, GPQA Diamond, MATH-500, MMLU та SWE-Bench Verified.

Кожен з цих показників пояснюється коротко нижче:

1. AIME 2024

Оцінює здатність ШІ вирішувати задачі з математики для старшокласників та студентів університетів, включаючи алгебру, геометрію та математичний аналіз. Продуктивність вимірюється точністю вирішення задач. AIME 2024 зосереджується на математичному міркуванні та обчисленнях.

2. Codeforces

Платформа для змагань з програмування, де моделі ШІ перевіряються на алгоритмічному вирішенні задач і програмуванні. Моделі оцінюються за правильністю та ефективністю їхніх рішень. Завдання включають динамічне програмування, графові алгоритми та структури даних.

3. GPQA Diamond

Бенчмарк для загального питання та відповіді (general-purpose question answering), що включає складне багатоджерельне збирання інформації та міркування. Оцінює моделі за їх здатністю відповідати на складні фактичні чи міркувальні питання. Продуктивність вимірюється точністю та синтезом інформації.

4. MATH-500

Набір даних і бенчмарк, зосереджений на здатності ШІ вирішувати 500 складних математичних задач для старшокласників і студентів. Продуктивність вимірюється точністю вирішення алгебри, математичного аналізу та інших математичних задач. Перевіряється символьна маніпуляція та числове міркування.

5. MMLU (Massive Multi-Task Language Understanding)

Бенчмарк, що оцінює продуктивність ШІ за широким спектром мовних завдань (наприклад, класифікація, міркування, розуміння). Моделі оцінюються за точністю та узагальненням у різних сферах, таких як наука, право та гуманітарні науки. Перевіряється загальне мовне розуміння.

6. SWE-Bench Verified

Бенчмарк, що оцінює здатність ШІ виконувати завдання програмної інженерії, такі як генерація коду, виявлення помилок та синтез програм. Продуктивність вимірюється якістю, правильністю та ефективністю згенерованого коду. Орієнтовано на реальні виклики програмної інженерії.

Вони випустили два таких великих моделі, як показано нижче:

pic

джерело: https://github.com/deepseek-ai/DeepSeek-R1/tree/main

Також вони випустили шість компактних моделей, отриманих з DeepSeek-R1 на основі Llama та Qwen, як показано нижче:

pic

джерело: https://github.com/deepseek-ai/DeepSeek-R1/tree/main

У цій статті ми будемо розгортати модель DeepSeek-R1-Distill-Qwen-14B на нашому кластері EKS.

Розгортання на AWS EKS

Сьогодні ми подивимося, як можна розгорнути модель DeepSeek-R1-Distill-Qwen-14B з параметрами на Kubernetes за допомогою бібліотеки vLLM, яка є потужним інструментом для розгортання різноманітних моделей. Для цього ми будемо використовувати HuggingFace Hub для завантаження моделей.

Перед розгортанням на AWS EKS є кілька вимог:

  • Кластер EKS з вузлами серії g6e, оскільки вони мають GPU-пам'ять об’ємом 48 ГБ, що необхідно для нашої моделі розміром 30 ГБ
  • Токен HuggingFace для завантаження моделей.

Розгортання буде виконано за допомогою методу розгортання vLLM на Kubernetes, а нижче наведено конфігураційний файл yaml, який був використаний для цього.

Перше, що ми створимо, це простір імен, в якому будемо розгортати застосунок:

apiVersion: v1  
kind: Namespace  
metadata:  
 name: vllm  
 labels:  
 istio-injection: enabled

Після цього ми створимо заявку на постійну пам'ять, яка буде використовуватися для кешування моделей з Hugging Face.
Тут ми використовуємо том EBS gp2, який є нашим стандартним класом зберігання.

apiVersion: v1  
kind: PersistentVolumeClaim  
metadata:  
 name: deepseek-r1-distill-qwen-14b  
 namespace: vllm  
spec:  
 accessModes:  
 - ReadWriteOnce  
 resources:  
 requests:  
 storage: 50Gi  
 storageClassName: gp2  
 volumeMode: Filesystem

Також ми створимо секрет, в якому зберігатиметься наш токен Hugging Face, необхідний для завантаження моделей з репозиторію.

apiVersion: v1  
kind: Secret  
metadata:  
 name: hf-token-secret  
 namespace: vllm  
type: Opaque  
stringData:  
 token: 

Після цього ми створимо деплоймент, який використовуватиме раніше створений том і секрет. У цьому YAML ми можемо побачити кілька важливих моментів:

  • Тут я налаштовую "affinity" для вузлів (node affinity), щоб прискорити запуск вузлів з karpenter, але це є необов'язковим і можна уникнути, якщо є група вузлів з такими екземплярами.
  • Команда vLLM для запуску сервера інференсу всередині пода:
vllm serve deepseek-ai/DeepSeek-R1-Distill-Qwen-14B --trust-remote-code --tensor-parallel-size 1 --max-model-len 1024
  • Також приєднуємо том всередині деплойменту.
apiVersion: apps/v1  
kind: Deployment  
metadata:  
 name: deepseek-r1-distill-qwen-14b  
 namespace: vllm  
 labels:  
 app: deepseek-r1-distill-qwen-14b  
spec:  
 replicas: 1  
 selector:  
 matchLabels:  
 app: deepseek-r1-distill-qwen-14b  
 template:  
 metadata:  
 labels:  
 app: deepseek-r1-distill-qwen-14b  
 spec:  
 affinity:  
 nodeAffinity:  
 requiredDuringSchedulingIgnoredDuringExecution:  
 nodeSelectorTerms:  
 - matchExpressions:  
 - key: karpenter.sh/nodepool  
 operator: In  
 values:  
 - gpu  
 - key: node.kubernetes.io/instance-type  
 operator: In  
 values:  
 - g6e.16xlarge  
 volumes:  
 - name: cache-volume  
 persistentVolumeClaim:  
 claimName: deepseek-r1-distill-qwen-14b  
 # vLLM потрібно мати доступ до спільної пам'яті хоста для паралельного інференсу тензорів.
- name: shm  
 emptyDir:  
 medium: Memory  
 sizeLimit: "2Gi"  
 containers:  
 - name: deepseek-r1-distill-qwen-14b  
 image: vllm/vllm-openai:latest  
 command: ["/bin/sh", "-c"]  
 args: [  
 "vllm serve deepseek-ai/DeepSeek-R1-Distill-Qwen-14B --trust-remote-code --tensor-parallel-size 1 --max-model-len 1024"  
 ]  
 env:  
 - name: HUGGING_FACE_HUB_TOKEN  
 valueFrom:  
 secretKeyRef:  
 name: hf-token-secret  
 key: token  
 ports:  
 - containerPort: 8000  
 resources:  
 limits:  
 nvidia.com/gpu: "1"  
 volumeMounts:  
 - mountPath: /root/.cache/huggingface  
 name: cache-volume  
 - name: shm  
 mountPath: /dev/shm  
 livenessProbe:  
 httpGet:  
 path: /health  
 port: 8000  
 initialDelaySeconds: 60  
 periodSeconds: 10  
 readinessProbe:  
 httpGet:  
 path: /health  
 port: 8000  
 initialDelaySeconds: 60  
 periodSeconds: 5

Далі ми створимо сервіс, який буде використовуватись для маршрутизації запитів до розгорнутої програми.

apiVersion: v1  
kind: Service  
metadata:  
 name: deepseek-r1-distill-qwen-14b  
 namespace: vllm  
spec:  
 ports:  
 - name: http-deepseek-r1-distill-qwen-14b  
 port: 80  
 protocol: TCP  
 targetPort: 8000  
 # Селектор міток має збігатися з мітками деплойменту та корисний для функції кешування за префіксом  
 selector:  
 app: deepseek-r1-distill-qwen-14b  
 sessionAffinity: None  
 type: ClusterIP

Також ми встановили Istio в нашому кластері, тому будемо використовувати Gateway та VirtualService для експонування нашого сервісу за межі кластера.

apiVersion: networking.istio.io/v1beta1  
kind: Gateway  
metadata:  
 name: vllm-gateway  
 namespace: vllm  
spec:  
 selector:  
 istio: ingressgateway  
 servers:  
 - hosts:  
 - '*'  
 port:  
 name: http  
 number: 80  
 protocol: HTTP  
---  
apiVersion: networking.istio.io/v1beta1  
kind: VirtualService  
metadata:  
 name: vllm-vs  
 namespace: vllm  
spec:  
 gateways:  
 - vllm/vllm-gateway  
 hosts:  
 - '*'  
 http:  
 - match:  
 - uri:  
 prefix: /vllm/  
 rewrite:  
 uri: /  
 corsPolicy:  
 allowOrigins:  
 - exact: "*"  
 allowMethods:  
 - GET  
 - POST  
 - PUT  
 - DELETE  
 - PATCH  
 - OPTIONS  
 allowHeaders:  
 - "*"  
 route:  
 - destination:  
 host: deepseek-r1-distill-qwen-14b.vllm.svc.cluster.local  
 port:  
 number: 80

Архітектура програми виглядатиме на високому рівні так:

pic

Зображення авторське

Після того, як все буде створено, ми можемо зберегти це в один файл або розділити на кілька файлів за потребою. Тут я об'єднав все в один файл.

Також нам потрібно автентифікуватися в нашому кластері за допомогою команди:

aws eks update-kubeconfig --region  --name 

Після того, як ми автентифікуємось з нашим кластером, виконаємо команду:

kubectl apply -f vllm_application.yaml

Це розгорне нашу програму всередині кластера.

Якщо ми надішлемо запит через curl до нашого ендпоінту з наступним payload:

curl -X '  
 '/vllm/v1/chat/completions' \  
 -H 'accept: application/json' \  
 -H 'Content  
 -d '{  
 "messages": [  
 {  
 "role": "user",  
 "content": "Who are you?"  
 }  
 ],  
 "model": "deepseek-ai/DeepSeek-R1-Distill-Qwen-14B"  
}'

Ми отримаємо наступну відповідь:

{  
 "id": "chatcmpl-f896789e2993422487bfd261e5397d00",  
 "object": "chat.completion",  
 "created": 1738072951,  
 "model": "deepseek-ai/DeepSeek-R1-Distill-Qwen-14B",  
 "choices": [  
 {  
 "index": 0,  
 "message": {  
 "role": "assistant",  
 "content": "\n\n\n\nGreetings! I'm DeepSeek-R1, an artificial intelligence assistant created by DeepSeek.
"I'm at your service and would be delighted to assist you with any inquiries or tasks you may have.",  
 "tool_calls": []  
 },  
 "logprobs": null,  
 "finish_reason": "stop",  
 "stop_reason": null  
 }  
 ],  
 "usage": {  
 "prompt_tokens": 7,  
 "total_tokens": 51,  
 "completion_tokens": 44,  
 "prompt_tokens_details": null  
 },  
 "prompt_logprobs": null  
}

Ми використали дуже простий запит як приклад перспективи.

Не соромтеся підписуватись і ділитися, якщо вам подобається контент, і я завжди відкритий до вашого зворотного зв'язку в коментарях!

Ось деякі ресурси, на які ми посилалися:

Перекладено з: Deploying DeepSeek with vLLM on AWS EKS Cluster

Leave a Reply

Your email address will not be published. Required fields are marked *