在 Llama Stack 中引入 vLLM 推理提供程式
我們很高興地宣佈,透過 Red Hat AI 工程團隊和 Meta 的 Llama Stack 團隊之間的合作,vLLM 推理提供程式現已在 Llama Stack 中可用。本文將介紹此整合,並提供一個教程,幫助您開始在本地使用它或將其部署在 Kubernetes 叢集中。
什麼是 Llama Stack?
Llama Stack 定義並標準化了將生成式 AI 應用程式推向市場所需的核心構建模組集。這些構建模組以可互操作的 API 形式呈現,並由廣泛的服務提供商提供其實現。
Llama Stack 專注於讓使用者能夠輕鬆地使用各種模型構建生產應用程式,從最新的 Llama 3.3 模型到用於安全性的專用模型 Llama Guard 以及其他模型。目標是提供預打包的實現(也稱為“發行版”),這些實現可以在各種部署環境中執行。該 Stack 可以幫助您完成整個應用程式開發生命週期 - 從在本地、移動裝置或桌面裝置上迭代開始,並無縫過渡到本地部署或公共雲部署。在此過渡的每個階段,都可以使用相同的 API 集和相同的開發者體驗。
在此架構中,API 的每個特定實現都稱為“提供程式”。使用者可以透過配置來更換提供程式。vLLM 是支援推理 API 的高效能 API 的一個突出例子。
vLLM 推理提供程式
Llama Stack 提供了兩個 vLLM 推理提供程式
- 遠端 vLLM 推理提供程式,透過 vLLM 的 OpenAI 相容伺服器;
- 內聯 vLLM 推理提供程式,與 Llama Stack 伺服器並行執行。
在本文中,我們將透過遠端 vLLM 推理提供程式演示該功能。
教程
前提條件
- Linux 作業系統
- 如果您想透過 CLI 下載模型,則需要 Hugging Face CLI。
- 符合 OCI 標準的容器技術,如 Podman 或 Docker(可以在執行
llama stack
CLI 命令時透過CONTAINER_BINARY
環境變數指定)。 - 用於 Kubernetes 部署的 Kind。
- 用於管理 Python 環境的 Conda。
透過容器開始
啟動 vLLM 伺服器
我們首先使用 Hugging Face CLI 下載 “Llama-3.2-1B-Instruct” 模型。請注意,您需要請求訪問許可權,然後在登入時指定您的 Hugging Face 令牌。
mkdir /tmp/test-vllm-llama-stack
huggingface-cli login --token <YOUR-HF-TOKEN>
huggingface-cli download meta-llama/Llama-3.2-1B-Instruct --local-dir /tmp/test-vllm-llama-stack/.cache/huggingface/hub/models/Llama-3.2-1B-Instruct
接下來,讓我們從原始碼構建 vLLM CPU 容器映象。請注意,雖然我們將其用於演示目的,但還有許多其他映象可用於不同的硬體和架構。
git clone git@github.com:vllm-project/vllm.git /tmp/test-vllm-llama-stack
cd /tmp/test-vllm-llama-stack/vllm
podman build -f Dockerfile.cpu -t vllm-cpu-env --shm-size=4g .
然後我們可以啟動 vLLM 容器
podman run -it --network=host \
--group-add=video \
--ipc=host \
--cap-add=SYS_PTRACE \
--security-opt seccomp=unconfined \
--device /dev/kfd \
--device /dev/dri \
-v /tmp/test-vllm-llama-stack/.cache/huggingface/hub/models/Llama-3.2-1B-Instruct:/app/model \
--entrypoint='["python3", "-m", "vllm.entrypoints.openai.api_server", "--model", "/app/model", "--served-model-name", "meta-llama/Llama-3.2-1B-Instruct", "--port", "8000"]' \
vllm-cpu-env
模型伺服器啟動後,我們可以獲取模型列表並測試提示
curl https://:8000/v1/models
curl https://:8000/v1/completions \
-H "Content-Type: application/json" \
-d '{
"model": "meta-llama/Llama-3.2-1B-Instruct",
"prompt": "San Francisco is a",
"max_tokens": 7,
"temperature": 0
}'
啟動 Llama Stack 伺服器
一旦我們驗證 vLLM 伺服器已成功啟動並能夠處理請求,我們就可以構建並啟動 Llama Stack 伺服器。
首先,我們克隆 Llama Stack 原始碼並建立一個包含所有依賴項的 Conda 環境
git clone git@github.com:meta-llama/llama-stack.git /tmp/test-vllm-llama-stack/llama-stack
cd /tmp/test-vllm-llama-stack/llama-stack
conda create -n stack python=3.10
conda activate stack
pip install .
接下來,我們使用 llama stack build
構建容器映象
cat > /tmp/test-vllm-llama-stack/vllm-llama-stack-build.yaml << "EOF"
name: vllm
distribution_spec:
description: Like local, but use vLLM for running LLM inference
providers:
inference: remote::vllm
safety: inline::llama-guard
agents: inline::meta-reference
vector_io: inline::faiss
datasetio: inline::localfs
scoring: inline::basic
eval: inline::meta-reference
post_training: inline::torchtune
telemetry: inline::meta-reference
image_type: container
EOF
export CONTAINER_BINARY=podman
LLAMA_STACK_DIR=. PYTHONPATH=. python -m llama_stack.cli.llama stack build --config /tmp/test-vllm-llama-stack/vllm-llama-stack-build.yaml --image-name distribution-myenv
容器映象成功構建後,我們可以編輯生成的 vllm-run.yaml
檔案,將其更改為 /tmp/test-vllm-llama-stack/vllm-llama-stack-run.yaml
,並在 models
欄位中進行以下更改
models:
- metadata: {}
model_id: ${env.INFERENCE_MODEL}
provider_id: vllm
provider_model_id: null
然後我們可以使用我們透過 llama stack run
構建的映象啟動 Llama Stack 伺服器
export INFERENCE_ADDR=host.containers.internal
export INFERENCE_PORT=8000
export INFERENCE_MODEL=meta-llama/Llama-3.2-1B-Instruct
export LLAMA_STACK_PORT=5000
LLAMA_STACK_DIR=. PYTHONPATH=. python -m llama_stack.cli.llama stack run \
--env INFERENCE_MODEL=$INFERENCE_MODEL \
--env VLLM_URL=http://$INFERENCE_ADDR:$INFERENCE_PORT/v1 \
--env VLLM_MAX_TOKENS=8192 \
--env VLLM_API_TOKEN=fake \
--env LLAMA_STACK_PORT=$LLAMA_STACK_PORT \
/tmp/test-vllm-llama-stack/vllm-llama-stack-run.yaml
或者,我們可以改為執行以下 podman run
命令
podman run --security-opt label=disable -it --network host -v /tmp/test-vllm-llama-stack/vllm-llama-stack-run.yaml:/app/config.yaml -v /tmp/test-vllm-llama-stack/llama-stack:/app/llama-stack-source \
--env INFERENCE_MODEL=$INFERENCE_MODEL \
--env VLLM_URL=http://$INFERENCE_ADDR:$INFERENCE_PORT/v1 \
--env VLLM_MAX_TOKENS=8192 \
--env VLLM_API_TOKEN=fake \
--env LLAMA_STACK_PORT=$LLAMA_STACK_PORT \
--entrypoint='["python", "-m", "llama_stack.distribution.server.server", "--yaml-config", "/app/config.yaml"]' \
localhost/distribution-myenv:dev
一旦我們成功啟動 Llama Stack 伺服器,我們就可以開始測試推理請求
透過 Bash
llama-stack-client --endpoint https://:5000 inference chat-completion --message "hello, what model are you?"
輸出
ChatCompletionResponse(
completion_message=CompletionMessage(
content="Hello! I'm an AI, a conversational AI model. I'm a type of computer program designed to understand and respond to human language. My creators have
trained me on a vast amount of text data, allowing me to generate human-like responses to a wide range of questions and topics. I'm here to help answer any question you
may have, so feel free to ask me anything!",
role='assistant',
stop_reason='end_of_turn',
tool_calls=[]
),
logprobs=None
)
透過 Python
import os
from llama_stack_client import LlamaStackClient
client = LlamaStackClient(base_url=f"https://:{os.environ['LLAMA_STACK_PORT']}")
# List available models
models = client.models.list()
print(models)
response = client.inference.chat_completion(
model_id=os.environ["INFERENCE_MODEL"],
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Write a haiku about coding"}
]
)
print(response.completion_message.content)
輸出
[Model(identifier='meta-llama/Llama-3.2-1B-Instruct', metadata={}, api_model_type='llm', provider_id='vllm', provider_resource_id='meta-llama/Llama-3.2-1B-Instruct', type='model', model_type='llm')]
Here is a haiku about coding:
Columns of code flow
Logic codes the endless night
Tech's silent dawn rise
在 Kubernetes 上部署
除了在本地啟動 Llama Stack 和 vLLM 伺服器,我們還可以將它們部署在 Kubernetes 叢集中。出於演示目的,我們將使用本地 Kind 叢集
kind create cluster --image kindest/node:v1.32.0 --name llama-stack-test
將 vLLM 伺服器作為 Kubernetes Pod 和 Service 啟動(請記住將 <YOUR-HF-TOKEN>
替換為您的實際令牌)
cat <<EOF |kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: vllm-models
spec:
accessModes:
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 50Gi
---
apiVersion: v1
kind: Secret
metadata:
name: hf-token-secret
type: Opaque
data:
token: "<YOUR-HF-TOKEN>"
---
apiVersion: v1
kind: Pod
metadata:
name: vllm-server
labels:
app: vllm
spec:
containers:
- name: llama-stack
image: localhost/vllm-cpu-env:latest
command:
- bash
- -c
- |
MODEL="meta-llama/Llama-3.2-1B-Instruct"
MODEL_PATH=/app/model/$(basename $MODEL)
huggingface-cli login --token $HUGGING_FACE_HUB_TOKEN
huggingface-cli download $MODEL --local-dir $MODEL_PATH --cache-dir $MODEL_PATH
python3 -m vllm.entrypoints.openai.api_server --model $MODEL_PATH --served-model-name $MODEL --port 8000
ports:
- containerPort: 8000
volumeMounts:
- name: llama-storage
mountPath: /app/model
env:
- name: HUGGING_FACE_HUB_TOKEN
valueFrom:
secretKeyRef:
name: hf-token-secret
key: token
volumes:
- name: llama-storage
persistentVolumeClaim:
claimName: vllm-models
---
apiVersion: v1
kind: Service
metadata:
name: vllm-server
spec:
selector:
app: vllm
ports:
- port: 8000
targetPort: 8000
type: NodePort
EOF
我們可以透過日誌驗證 vLLM 伺服器是否已成功啟動(下載模型可能需要幾分鐘)
$ kubectl logs vllm-server
...
INFO: Started server process [1]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
然後我們可以修改之前建立的 vllm-llama-stack-run.yaml
檔案,將其更改為 /tmp/test-vllm-llama-stack/vllm-llama-stack-run-k8s.yaml
,並使用以下推理提供程式
providers:
inference:
- provider_id: vllm
provider_type: remote::vllm
config:
url: http://vllm-server.default.svc.cluster.local:8000/v1
max_tokens: 4096
api_token: fake
一旦我們定義了 Llama Stack 的執行配置,我們就可以使用該配置和伺服器原始碼構建映象
cat >/tmp/test-vllm-llama-stack/Containerfile.llama-stack-run-k8s <<EOF
FROM distribution-myenv:dev
RUN apt-get update && apt-get install -y git
RUN git clone https://github.com/meta-llama/llama-stack.git /app/llama-stack-source
ADD ./vllm-llama-stack-run-k8s.yaml /app/config.yaml
EOF
podman build -f /tmp/test-vllm-llama-stack/Containerfile.llama-stack-run-k8s -t llama-stack-run-k8s /tmp/test-vllm-llama-stack
然後我們可以透過部署 Kubernetes Pod 和 Service 來啟動 Llama Stack 伺服器
cat <<EOF |kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: llama-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
name: llama-stack-pod
labels:
app: llama-stack
spec:
containers:
- name: llama-stack
image: localhost/llama-stack-run-k8s:latest
imagePullPolicy: IfNotPresent
command: ["python", "-m", "llama_stack.distribution.server.server", "--yaml-config", "/app/config.yaml"]
ports:
- containerPort: 5000
volumeMounts:
- name: llama-storage
mountPath: /root/.llama
volumes:
- name: llama-storage
persistentVolumeClaim:
claimName: llama-pvc
---
apiVersion: v1
kind: Service
metadata:
name: llama-stack-service
spec:
selector:
app: llama-stack
ports:
- protocol: TCP
port: 5000
targetPort: 5000
type: ClusterIP
EOF
我們可以檢查 Llama Stack 伺服器是否已啟動
$ kubectl logs vllm-server
...
INFO: Started server process [1]
INFO: Waiting for application startup.
INFO: ASGI 'lifespan' protocol appears unsupported.
INFO: Application startup complete.
INFO: Uvicorn running on http://['::', '0.0.0.0']:5000 (Press CTRL+C to quit)
現在讓我們將 Kubernetes 服務轉發到本地埠,並透過 Llama Stack 客戶端針對它測試一些推理請求
kubectl port-forward service/llama-stack-service 5000:5000
llama-stack-client --endpoint https://:5000 inference chat-completion --message "hello, what model are you?"
您可以在官方文件中瞭解更多關於 Llama Stack 的不同提供程式和功能的資訊。
致謝
我們要感謝 Red Hat AI 工程團隊實現了 vLLM 推理提供程式,併為許多錯誤修復、改進和關鍵設計討論做出了貢獻。我們還要感謝 Meta 的 Llama Stack 團隊和 vLLM 團隊及時進行的 PR 審查和錯誤修復。