title: “Model Plane: EKS 上的 vLLM + LiteLLM” weight: 100
在本模块中,我们将看到研讨会中的每个 agent 如何访问单一的模型端点,无论属于哪个方向。Qwen2.5-3B 在 AWS Inferentia 上通过 vLLM 运行,而 LiteLLM 位于其前面(也位于 Bedrock 前面),作为每个 agent 都会与之通信的唯一代理。这里无需我们安装任何东西。两者都已在运行。
vLLM 提供自托管模型(Inferentia 上的 Qwen2.5-3B)。LiteLLM 是一个轻量的 OpenAI 兼容代理,根据模型名称路由请求:
model: qwen2-5-3b-neuron → vLLM(自管理方向)model: nova-lite → Amazon Bedrock(集成方向)由于每个 agent 都调用 LiteLLM,而不是直接调用 vLLM 或 Bedrock,切换方向就变成了 agent 中的一行更改:将 model_id 从 "qwen2-5-3b-neuron" 切换为 "nova-lite"。相同的 OpenAIModel 客户端,相同的 base URL,相同的代码路径。其余的都由代理处理,包括通过 LiteLLM pod 上的 Pod Identity 为 Bedrock 提供的 AWS IAM。
vLLM 是一个高吞吐量的 LLM 服务引擎,具备持续批处理、paged attention 以及标准的 chat-completions 风格 API。它运行在用于 Inferentia 和 Trainium 的 AWS Neuron SDK 上。
AWS Inferentia 是一款专为高性能、低成本推理而打造的 ML 加速器。Inferentia2(inf2)实例拥有多达 12 个 NeuronCores 和 384 GB 的 HBM。
LiteLLM 在前端使用 OpenAI chat-completions 格式进行通信,在后端将其转换为 100 多种后端中的任意一种(vLLM、Bedrock、OpenAI、Azure 等)。在本研讨会中,我们将它用作每个 agent 都会与之通信的模型平面(model plane)。它还会将自己的 span 转发到 Langfuse,因此稍后我们会在每个 agent 的 trace 旁边看到代理级别的 trace。

Agent pod (any track)
OpenAIModel(base_url=LITELLM_BASE_URL)
│
▼
┌─── LiteLLM Proxy (litellm namespace) ────┐
│ qwen2-5-3b-neuron → vLLM │
│ nova-lite → Bedrock (Pod Identity)│
└────┬────────────────────────────────┬────┘
▼ ▼
vLLM on Inferentia Amazon Bedrock
(Qwen2.5-3B) (us.amazon.nova-2-lite-v1:0)
在研讨会设置期间部署:
aws.amazon.com/neuroncore 时,Karpenter 会预置 inf2.xlargeqwen2-5-3b-neuron.vllm.svc.cluster.local:8000litellm.litellm.svc.cluster.local:4000(每个 agent 都会与之通信的单一 URL)bedrock:Converse* + bedrock:InvokeModel* 的 IAM 角色,附加到 litellm service account,因此只有代理(而非 agent)持有 Bedrock 权限两个 namespace 都应处于 Running 状态:
kubectl get pods -n vllm -l app=qwen2-5-3b-neuron
kubectl get pods -n litellm
如果 LiteLLM pod 不处于 `Running` 状态,请重启部署:
`kubectl rollout restart deploy/litellm -n litellm && kubectl rollout status deploy/litellm -n litellm --timeout=120s`
检查加载到代理中的 LiteLLM 模型路由表:
kubectl logs deploy/litellm -n litellm | grep -iE -B2 -A2 "qwen|nova-lite"
Initialized Success Callbacks - ['langfuse']
LiteLLM: Proxy initialized with Config, Set models:
qwen3-8b-neuron
nova-lite
INFO: 10.0.6.254:51626 - "GET /health/readiness HTTP/1.1" 200 OK
INFO: 10.0.6.254:51630 - "GET /health/readiness HTTP/1.1" 200 OK
我们应该在启动日志中同时看到 qwen2-5-3b-neuron 和 nova-lite。
获取 ingress URL 和生成的 master key。我们将同时用它们进行 curl 测试,稍后还会在下面的管理 UI 中再次使用:
LITELLM_URL="http://$(kubectl get ingress -n litellm litellm -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')"
LITELLM_KEY=$(kubectl get cm agent-config -n default -o jsonpath='{.data.LITELLM_API_KEY}')
echo "URL: $LITELLM_URL"
echo "Key: $LITELLM_KEY"
如果 $LITELLM_URL 打印为空字符串,则说明 ALB 仍在预置中。等待 60 秒后重新运行。master key 是 Terraform 为每次部署生成并写入 agent-config ConfigMap 的随机值。
使用自管理模型名称访问代理。该请求会发送到 Inferentia 上的 vLLM:
curl -s $LITELLM_URL/v1/chat/completions \
-H "Authorization: Bearer $LITELLM_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "qwen2-5-3b-neuron",
"messages": [{"role": "user", "content": "What is 2+2?"}],
"max_tokens": 100
}'
现在切换模型名称。代理会将其改为路由到 Bedrock。agent 代码既不会知道也不会在意:
curl -s $LITELLM_URL/v1/chat/completions \
-H "Authorization: Bearer $LITELLM_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "nova-lite",
"messages": [{"role": "user", "content": "What is 2+2?"}],
"max_tokens": 100
}'
相同的端点,相同的 payload 结构,不同的后端。这正是关键所在。
LiteLLM 还在 /ui 提供了一个小型管理 UI。由同一个 ALB 提供服务。在浏览器中打开它并输入 LiteLLM key:
echo "$LITELLM_URL/ui"
echo "$LITELLM_KEY"
使用用户名 admin 和我们上面打印出来的 $LITELLM_KEY 值作为密码登录。可点击的内容有:
curl 访问的列表相同| 参数 | 值 | 描述 |
|---|---|---|
| Model | Qwen/Qwen2.5-3B-Instruct | 30 亿参数模型,使用 optimum-neuron 为 Neuron 预编译 |
| Instance | inf2.xlarge | 1 个 Neuron 设备,2 个 NeuronCores |
| Image | vllm-neuron: qwen2.5-3b-optimum-neuron | 预编译模型已烘焙进 Docker 镜像 |
| tensor-parallel-size | 2 | 将模型分布在 2 个 NeuronCores 上 |
| max-model-len | 8192 | 最大上下文长度 |
| max-num-seqs | 2 | 最大并发序列数 |
| 设置 | 值 | 描述 |
|---|---|---|
| Aliases | qwen2-5-3b-neuron,nova-lite |
agent 在 model_id 中使用的名称 |
| vLLM upstream | http://qwen2-5-3b-neuron.vllm.svc.cluster.local:8000/v1 |
集群内 Service |
| Bedrock upstream | bedrock/us.amazon.nova-2-lite-v1:0 |
区域默认取自 pod 的 AWS 环境 |
| Callbacks | langfuse |
将 LiteLLM 自己的 span 转发到研讨会的 Langfuse 项目 |
| Master key | $LITELLM_KEY |
由 Terraform 生成,通过 agent-config ConfigMap 以 LITELLM_API_KEY 的形式暴露 |
OpenAIModel(base_url=LITELLM_BASE_URL, model_id="qwen2-5-3b-neuron")。本方向中每个实验的 Python 完全相同。model 字段,在其配置中查找路由,调用上游Converse,并将响应转换回 OpenAI 格式