1. 项目概述一个为LLM应用量身定制的文档化部署方案如果你正在尝试将大语言模型LLM从实验室的Demo状态推向一个可供团队或用户稳定使用的服务那么你大概率会遇到和我一样的困境部署过程繁琐、环境依赖复杂、配置项多如牛毛而且每次换台机器或新来一个同事都得重新走一遍“踩坑”之路。varunvasudeva1/llm-server-docs这个项目正是为了解决这个痛点而生的。它不是一个全新的LLM推理框架而是一个高度集成、开箱即用且文档详尽的部署方案其核心价值在于将vLLM、Ollama等业界优秀的推理引擎与FastAPI、Gradio等Web服务框架通过一套精心设计的Docker Compose配置和脚本封装起来让你能像部署一个普通Web应用一样轻松拉起一个功能完备的LLM服务集群。简单来说它把搭建一个生产可用的LLM服务所需的所有“脏活累活”——包括模型下载、服务启动、API暴露、负载均衡、监控看板——都打包好了并提供了清晰的文档告诉你每一步在做什么以及如何按需定制。这特别适合中小型团队、独立开发者或者任何希望快速验证LLM应用原型而不想在前期的工程化部署上耗费过多精力的人。我最初接触它是因为需要为一个内部知识库问答系统提供稳定的模型服务从手动折腾到采用这套方案部署时间从以“天”计缩短到了以“小时”计并且后续的维护和扩展也变得清晰可控。2. 核心架构与设计思路拆解2.1 为什么选择“文档化”与“一体化”设计在LLM服务部署领域工具链已经非常丰富。vLLM以其极高的推理吞吐量和高效的内存管理闻名Ollama则以对Mac和消费级硬件的友好以及简单的模型管理著称Text Generation Inference (TGI)则背靠Hugging Face生态。然而这些工具大多专注于推理引擎本身。要将它们变成服务你还需要考虑如何提供一个统一的HTTP API如何集成一个方便调试和演示的Web UI如何管理多个模型实例如何配置身份验证和限流llm-server-docs项目的设计思路就是做这个“最后一公里”的集成。它采用了“文档化”优先的设计。项目仓库里不仅有代码和配置更有大量解释性的Markdown文档。这些文档并非简单的命令罗列而是会阐述每个组件的作用、配置项的含义、以及不同部署模式如本地开发、生产部署下的考量。这种设计极大地降低了使用门槛即使你对Docker或LLM部署不熟悉也能通过阅读文档理解整个系统的运作原理。“一体化”则体现在其docker-compose.yml文件的精心编排上。一个典型的部署会包含多个服务一个或多个模型推理服务可能是vLLM或Ollama实例一个作为API网关和负载均衡器的FastAPI应用一个用于交互式测试的Gradio前端以及可选的监控工具如Prometheus、Grafana。所有这些服务通过Docker网络互联依赖关系清晰一键即可启动整个栈。2.2 核心组件选型与职责分析让我们深入看看这个方案通常包含哪些核心组件以及为什么是它们推理引擎层vLLM / Ollama这是系统的核心算力来源。项目通常会同时支持或提供两种配置。vLLM当你有强大的GPU服务器如NVIDIA A100, H100并追求极致性能时vLLM是首选。它通过PagedAttention算法显著优化了显存使用能同时处理大量并发请求。在这个方案中vLLM通常以--api-key方式启动提供OpenAI兼容的API并配置好模型路径、Tensor并行等参数。Ollama如果你的环境是MacApple Silicon、消费级GPU或者你更看重极简的模型拉取和管理ollama pull,ollama run那么Ollama是更友好的选择。它同样提供API但模型格式和运行方式与vLLM不同。本方案通过Docker封装Ollama使其能与其他服务协同工作。API服务与网关层FastAPI这是业务逻辑的核心层。直接让前端或客户端调用推理引擎的原始API有时不够灵活。因此本项目通常会包含一个自定义的FastAPI应用。它的职责包括API路由与转发提供一个统一的端点如/v1/chat/completions将请求路由到后端的vLLM或Ollama实例。负载均衡如果启动了多个模型实例用于扩容或服务不同模型FastAPI应用可以实现简单的轮询或基于负载的路由。请求/响应格式化适配不同引擎的API细微差异为上游调用者提供稳定、统一的接口通常是OpenAI API格式。增强功能可以方便地在此层添加身份验证、请求日志、速率限制、输入输出预处理等中间件。交互式前端层Gradio对于调试、演示和内部测试一个可视化的界面不可或缺。Gradio能快速构建一个Web UI用于输入提示词、调整参数如temperature, top_p、实时查看模型输出。它通过调用上述FastAPI网关的接口来工作使得测试变得直观。编排与部署层Docker Docker Compose这是将以上所有组件粘合在一起的关键。每个组件都被封装在一个独立的Docker容器中。docker-compose.yml文件定义了服务之间的关系、网络配置、卷挂载用于持久化模型数据、日志和环境变量。这使得整个系统具有极佳的可移植性和可复现性。注意这套架构是一种“样板间”式的设计。它给出了一个经过验证的最佳实践组合但你完全可以根据自己的需求进行删减或替换。例如如果你不需要Web UI可以注释掉Gradio服务如果你已经有Kubernetes集群可以将Docker Compose配置转化为K8s的Deployment和Service。3. 从零开始的详细部署实操指南假设我们在一台装有NVIDIA GPU的Ubuntu服务器上部署一个基于vLLM和Llama 3模型的完整服务栈。以下是步步为营的操作过程。3.1 环境准备与前置检查首先确保你的基础环境就绪。# 1. 更新系统并安装基础工具 sudo apt update sudo apt upgrade -y sudo apt install -y git curl wget # 2. 安装 Docker 和 Docker Compose Plugin # 卸载旧版本如有 sudo apt-get remove docker docker-engine docker.io containerd runc # 设置仓库 sudo apt-get install -y ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod ar /etc/apt/keyrings/docker.asc echo \ deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release echo $VERSION_CODENAME) stable | \ sudo tee /etc/apt/sources.list.d/docker.list /dev/null # 安装 Docker sudo apt-get update sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin # 将当前用户加入docker组避免每次用sudo sudo usermod -aG docker $USER newgrp docker # 或注销重新登录使组生效 # 验证安装 docker --version docker compose version # 3. 安装 NVIDIA Container Toolkit (GPU支持关键) distribution$(. /etc/os-release;echo $ID$VERSION_ID) curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | \ sed s#deb https://#deb [signed-by/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g | \ sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list sudo apt-get update sudo apt-get install -y nvidia-container-toolkit sudo nvidia-ctk runtime configure --runtimedocker sudo systemctl restart docker # 验证GPU在容器内可用 docker run --rm --runtimenvidia --gpus all nvidia/cuda:12.1.0-base-ubuntu22.04 nvidia-smi如果最后一条命令能成功输出GPU信息说明Docker的GPU支持已配置正确。3.2 获取项目与初步配置接下来克隆项目仓库并了解其结构。# 克隆项目假设项目在GitHub上请替换为实际仓库地址 git clone https://github.com/varunvasudeva1/llm-server-docs.git cd llm-server-docs # 查看核心目录结构 ls -la # 你通常会看到类似以下的结构 # - docker-compose.yml # 核心编排文件 # - .env.example # 环境变量示例 # - api/ # FastAPI 网关应用代码 # - models/ # 模型下载或挂载目录可能为空 # - scripts/ # 辅助脚本如模型下载脚本 # - docs/ # 详细文档 # - prometheus/ # 监控配置如果包含 # - grafana/ # 仪表板配置如果包含关键第一步配置环境变量。这是定制化部署的核心。复制示例文件并根据你的情况修改。cp .env.example .env # 使用你喜欢的编辑器打开 .env 文件例如 nano 或 vim nano .env一个典型的.env文件需要配置以下关键项# 模型配置 MODEL_NAMEmeta-llama/Meta-Llama-3-8B-Instruct # Hugging Face模型ID MODEL_PATH/data/models/llama-3-8b-instruct # 容器内模型挂载路径本地路径会映射到此 # 如果你从其他地方下载了模型权重可以修改 MODEL_PATH 指向本地目录并设置 MODEL_NAME 为本地路径 # vLLM 服务配置 VLLM_HOSTvllm-server VLLM_PORT8000 VLLM_API_KEYyour-vllm-api-key-here # 建议设置为一个强密码用于服务间认证 # FastAPI 网关配置 API_HOST0.0.0.0 API_PORT8080 API_KEYyour-gateway-api-key-here # 对外提供的API密钥客户端调用时需携带 # 硬件与性能配置 GPU_DEVICE0 # 使用哪块GPU多卡可用“0,1” MAX_MODEL_LEN8192 # 模型最大上下文长度 TENSOR_PARALLEL_SIZE1 # 张量并行大小单卡为1多卡可增加 # 其他服务配置如Gradio GRADIO_SERVER_PORT7860实操心得MODEL_PATH的配置容易混淆。这里配置的是容器内部的路径。在docker-compose.yml中你会看到类似- ./models:/data/models的卷挂载配置。这意味着你宿主机上的./models目录即项目下的models文件夹会被挂载到容器内的/data/models。因此如果你提前将模型文件下载到了./models/llama-3-8b-instruct下那么MODEL_PATH就应设置为/data/models/llama-3-8b-instruct。模型文件通常包括pytorch_model-*.bin,config.json,tokenizer.json等。3.3 模型准备与下载策略模型文件通常很大Llama 3 8B大约15GB。你有两种主要方式准备模型方式一使用内置脚本下载推荐给首次使用者项目可能提供了下载脚本例如scripts/download_model.sh。运行前请确保你有Hugging Face的访问令牌HF_TOKEN特别是对于gated模型如Llama 3。# 首先将你的HF_TOKEN设置到环境变量中 export HF_TOKENyour_huggingface_token_here # 然后运行脚本假设脚本存在且接受模型ID和输出路径参数 bash scripts/download_model.sh meta-llama/Meta-Llama-3-8B-Instruct ./models/llama-3-8b-instruct下载过程可能需要较长时间取决于你的网络带宽。方式二手动下载与放置如果你已经通过其他方式如git lfs或手动下载获得了模型文件只需将其放置在./models目录下对应的子文件夹中确保文件结构符合Hugging Facetransformers库的预期。方式三直接使用Hugging Face Hub在线拉取这是最简单但启动慢的方式。你只需在.env中设置MODEL_NAME为Hugging Face模型ID并将MODEL_PATH留空或注释掉。vLLM在首次启动时会自动从网上下载。但这要求容器运行时能访问外网且首次启动等待时间很长。注意事项对于生产环境强烈建议采用方式一或二将模型文件预先放置在本地或网络存储中。在线拉取方式不稳定且每次重建容器都可能重复下载。3.4 启动完整服务栈模型准备就绪后启动服务就变得非常简单。# 在项目根目录即 docker-compose.yml 所在目录执行 docker compose up -d这个命令会执行以下操作根据docker-compose.yml构建或拉取所有服务的Docker镜像。按照定义创建独立的Docker网络使服务间能通过服务名如vllm-server,api-gateway互相访问。按依赖顺序启动所有容器-d表示在后台运行。使用以下命令查看服务状态和日志# 查看所有容器状态 docker compose ps # 应该看到 vllm-server, api-gateway, gradio-ui 等容器处于 “Up” 状态。 # 跟踪查看某个服务的日志非常有用特别是首次启动时 docker compose logs -f vllm-server # 在vLLM日志中你会看到模型加载进度加载完成后会显示“Uvicorn running on...”等信息。3.5 验证服务与初步测试所有服务启动成功后我们可以进行验证。验证vLLM引擎vLLM服务通常直接暴露其OpenAI兼容的API在8000端口容器内可能未映射到宿主机。我们可以通过网关来间接测试但也可以直接进入容器内部测试。# 进入vllm-server容器 docker compose exec vllm-server bash # 在容器内使用curl测试本地端点 curl http://localhost:8000/v1/models如果返回一个包含模型信息的JSON说明vLLM运行正常。验证FastAPI网关网关服务通常将端口如8080映射到宿主机。这是你对外提供的主要API入口。# 在宿主机上测试网关健康检查端点如果设计了的话 curl http://localhost:8080/health # 测试OpenAI兼容的聊天接口记得使用你在.env中设置的API_KEY curl http://localhost:8080/v1/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer your-gateway-api-key-here \ -d { model: meta-llama/Meta-Llama-3-8B-Instruct, messages: [{role: user, content: Hello, how are you?}], max_tokens: 50 }如果收到一个包含模型回复的JSON响应恭喜你核心API服务已经打通使用Gradio UI进行交互测试Gradio服务通常将7860端口映射出来。直接在浏览器中打开http://你的服务器IP:7860。你应该能看到一个聊天界面。在界面中输入问题点击提交它应该会通过网关调用模型并返回结果。这是最直观的测试方式。4. 核心配置深度解析与调优部署成功只是第一步。要让服务稳定、高效地运行必须理解关键配置项并进行调优。4.1 vLLM引擎参数详解在docker-compose.yml中vLLM服务的启动命令可能类似这样环境变量已替换services: vllm-server: image: vllm/vllm-openai:latest command: --model ${MODEL_PATH:-${MODEL_NAME}} --served-model-name ${MODEL_NAME} --api-key ${VLLM_API_KEY} --host 0.0.0.0 --port ${VLLM_PORT} --tensor-parallel-size ${TENSOR_PARALLEL_SIZE:-1} --max-model-len ${MAX_MODEL_LEN:-8192} --gpu-memory-utilization 0.9 --disable-log-requests --disable-log-stats deploy: resources: reservations: devices: - driver: nvidia count: all capabilities: [gpu]让我们拆解关键参数--tensor-parallel-size张量并行大小。如果你的单张GPU显存不足以放下整个模型例如70B模型或者你想利用多卡提高吞吐量可以将此值设为可用的GPU数量。vLLM会自动将模型参数拆分到多张卡上。计算依据主要看模型参数量和GPU显存。例如Llama 3 70B的FP16权重约140GB。假设你有4张80GB的A100tensor-parallel-size4可以将模型平均分配到每张卡约35GB加上KVCache等开销是可行的。--max-model-len最大模型长度。这决定了模型能处理的最大上下文令牌数。设置得越高单个请求消耗的显存KVCache就越多。调优建议根据你的应用场景设定。如果是长文档摘要或对话历史很长需要调高如32k, 128k。但要注意这会显著增加显存占用。公式近似为KVCache内存 ≈ 2 * 层数 * 头数 * 头维度 * max_model_len * 批次大小 * 数据类型字节数。这是一个简化公式实际vLLM的PagedAttention会更高效。--gpu-memory-utilizationGPU内存利用率。默认0.9即预留90%的GPU显存给模型权重和KVCache。如果你的GPU上还运行其他任务可以适当调低。如果此服务独占GPU可以保持0.9甚至尝试0.95以充分利用显存。--disable-log-requests和--disable-log-stats禁用详细日志以提升性能。在生产环境中建议开启除非你需要详细的调试信息。4.2 FastAPI网关的增强功能实现项目自带的api/目录下的FastAPI应用是定制化的关键。我们来看看通常可以如何增强它。添加全局API密钥认证在api/main.py中你可以添加一个依赖项来验证请求头中的API Key。from fastapi import FastAPI, Depends, HTTPException, Header from typing import Annotated app FastAPI() API_KEY os.getenv(API_KEY, default-secret-key) # 从环境变量读取 async def verify_api_key(api_key: Annotated[str | None, Header(aliasAuthorization)] None): if api_key is None or api_key ! fBearer {API_KEY}: raise HTTPException(status_code403, detailInvalid or missing API Key) return True app.post(/v1/chat/completions) async def chat_completion(valid: bool Depends(verify_api_key), request: ChatCompletionRequest): # 只有通过认证的请求才能到达这里 # ... 转发逻辑 ...实现简单的负载均衡如果你在docker-compose.yml中启动了多个vllm-server实例例如通过scale命令可以在网关中实现一个简单的轮询。import itertools import aiohttp from fastapi import HTTPException # 假设有多个vLLM后端 VLLM_BACKENDS [ http://vllm-server-1:8000, http://vllm-server-2:8000, ] backend_cycle itertools.cycle(VLLM_BACKENDS) app.post(/v1/chat/completions) async def chat_completion(request: ChatCompletionRequest): backend_url next(backend_cycle) async with aiohttp.ClientSession() as session: try: async with session.post( f{backend_url}/v1/chat/completions, jsonrequest.dict(), headers{Authorization: fBearer {VLLM_API_KEY}}, timeout30 ) as resp: return await resp.json() except aiohttp.ClientError as e: raise HTTPException(status_code502, detailfBackend error: {e})请求/响应日志与监控你可以使用FastAPI的中间件来记录每一个请求和响应便于问题排查和用量分析。import logging import time from fastapi import Request logging.basicConfig(levellogging.INFO) logger logging.getLogger(__name__) app.middleware(http) async def log_requests(request: Request, call_next): start_time time.time() response await call_next(request) process_time time.time() - start_time logger.info( fMethod{request.method} Path{request.url.path} fStatus{response.status_code} Duration{process_time:.3f}s ) return response4.3 生产环境部署考量对于生产环境仅靠基础的Docker Compose可能不够需要考虑以下方面高可用与反向代理使用nginx或traefik作为入口反向代理实现SSL终止、负载均衡和静态文件服务。可以将它们也加入docker-compose.yml。services: nginx: image: nginx:alpine ports: - 443:443 - 80:80 volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro - ./ssl_certs:/etc/nginx/ssl:ro depends_on: - api-gateway networks: - llm-network在nginx.conf中配置 upstream 指向api-gateway:8080。模型热更新如何在不中断服务的情况下更新模型一种策略是采用蓝绿部署。准备两套环境A和B每套环境有自己的vLLM服务组和网关。通过切换反向代理的 upstream 来实现流量切换。本项目结构清晰易于复制出另一套环境。资源限制与监控在docker-compose.yml中为每个服务设置资源限制防止单个服务耗尽主机资源。services: vllm-server: # ... deploy: resources: limits: cpus: 4.0 memory: 48G reservations: devices: - driver: nvidia count: 1 capabilities: [gpu]同时集成prometheus和grafana来监控服务健康度、请求延迟、GPU利用率等指标。项目如果已经包含相关配置直接启用即可。日志集中管理配置Docker的日志驱动将容器日志发送到elasticsearch、loki或云服务商的日志服务便于集中查询和分析。5. 常见问题排查与实战经验分享即使按照文档操作在实际部署中也可能遇到各种问题。以下是我在多次部署中积累的常见问题及解决方法。5.1 模型加载失败这是最常见的问题通常表现为vLLM容器不断重启日志中出现Failed to load model或CUDA out of memory错误。问题表现docker compose logs vllm-server显示RuntimeError: CUDA out of memory或NotFoundError: No such file or directory [模型文件]。排查步骤检查模型路径确认.env中的MODEL_PATH或MODEL_NAME正确无误。进入vLLM容器检查/data/models目录下是否存在模型文件 (ls -la /data/models)。检查模型文件完整性Hugging Face模型通常包含多个文件pytorch_model-00001-of-000xx.bin,config.json,tokenizer.model等。确保所有文件都已下载完整。可以尝试在容器内用Python简单导入测试python -c from transformers import AutoModelForCausalLM; model AutoModelForCausalLM.from_pretrained(/data/models/your-model, torch_dtypeauto, device_mapauto)。检查GPU和驱动运行nvidia-smi确认GPU被Docker识别。确保NVIDIA Container Toolkit已正确安装。在容器内运行nvidia-smi确认CUDA可用。调整显存参数如果报错是OOM尝试降低--gpu-memory-utilization如从0.9降到0.8或者减小--max-model-len。对于非常大的模型确保--tensor-parallel-size设置正确能够将模型拆分到多张卡上。解决方案速查表错误信息/现象可能原因解决方案CUDA error: out of memory1. 模型太大单卡放不下。2.max-model-len设置过高。3. 有其他进程占用显存。1. 增加tensor-parallel-size使用多卡。2. 降低max-model-len或gpu-memory-utilization。3. 排查并停止无关进程或使用nvidia-smi查看占用。No such file or directory: /data/models/...1..env中MODEL_PATH配置错误。2. 模型文件未下载或路径不对。3. Docker卷挂载失败。1. 检查.env文件。2. 确认宿主机./models目录下有文件并检查Docker Compose中的 volumes 映射。3. 尝试在容器内手动列出目录。Failed to fetch model files from HF Hub1. 网络问题无法访问Hugging Face。2. 对于gated模型缺少HF_TOKEN。1. 配置容器网络代理或使用离线模型。2. 在.env或容器环境中设置HF_TOKEN变量。Killed(容器突然退出)通常是被系统OOM Killer终止因为内存非显存不足。增加宿主机的物理内存或Swap空间或在Docker Compose中为服务设置内存限制 (mem_limit)。5.2 API请求超时或无响应服务启动了但通过网关或Gradio调用时超时。问题表现curl命令或Gradio界面长时间转圈最后返回504 Gateway Timeout或连接错误。排查步骤逐层测试首先测试vLLM服务本身是否正常 (curl http://localhost:8000/v1/models在容器内)。然后测试网关服务 (curl http://localhost:8080/health)。最后测试Gradio到网关的连通性。这能帮你定位问题发生在哪一层。检查网络确保所有服务在同一个Docker自定义网络中在docker-compose.yml中定义。使用docker network inspect llm-server-docs_default查看网络详情和容器IP。检查日志仔细查看api-gateway和vllm-server的日志 (docker compose logs api-gateway)看是否有错误堆栈。常见错误包括连接被拒绝端口不对、认证失败API Key不匹配、请求格式错误。检查资源模型推理可能非常耗时。如果提示词很长或生成令牌数 (max_tokens) 设置很大请求处理时间会很长。查看GPU利用率 (nvidia-smi) 和容器CPU/内存使用情况 (docker stats)看是否存在资源瓶颈。解决方案增加超时时间在FastAPI网关转发请求到vLLM时增加aiohttp客户端的timeout参数例如设为300秒。优化请求在客户端设置合理的max_tokens避免生成过长内容。对于流式响应确保客户端能正确处理流。服务健康检查在Docker Compose中为服务配置healthcheck确保只有健康的服务才接收流量。5.3 性能调优实战心得部署成功之后如何让服务跑得更快、更稳这里有一些非官方文档的小技巧。量化模型以降低显存和提升速度如果你的模型支持如Llama系列使用GPTQ、AWQ或vLLM自带的--quantization参数进行量化可以大幅减少显存占用从而允许更大的批次处理或更长的上下文。例如使用--quantization awq并加载对应的AWQ量化模型。注意量化通常会轻微降低输出质量需要根据任务权衡。调整vLLM的--block-size和--swap-space--block-size是PagedAttention的块大小默认16。对于非常长的上下文32k可以适当增大如32可能有助于减少内存碎片。--swap-space是CPU和GPU之间交换内存的大小当GPU显存不足时vLLM可以将部分KVCache交换到CPU内存。如果你的系统内存充足可以适当调大此值如--swap-space 16表示16GiB但这会显著增加延迟。使用连续批处理Continuous Batching的优势vLLM默认开启连续批处理这是其高吞吐的关键。这意味着无需等待一个请求完成再处理下一个而是动态地将新请求插入到正在进行的批次中。为了最大化利用此特性客户端应尽可能采用异步并发请求而不是同步顺序请求。例如使用Python的asyncio和aiohttp同时发送多个请求。监控与告警除了基础的docker stats建议部署prometheusgrafana。关键指标包括vLLM:vllm:num_requests_running,vllm:num_requests_swapped,vllm:request_latency_seconds。系统: GPU利用率、显存使用率、容器CPU/内存。网关: 请求速率、延迟分布、错误率。 设置告警规则当GPU利用率持续低于某个阈值可能表示请求不足或请求延迟P99过高时及时通知。最后关于扩展性当单台服务器的GPU资源成为瓶颈时本项目的架构可以自然地扩展到多机。你可以将vLLM服务部署到多台GPU服务器上每台服务器运行一个或多个vLLM实例。然后修改FastAPI网关的配置使其知晓所有这些后端的地址并实现更复杂的负载均衡策略如基于模型版本、基于负载。网关本身可以水平扩展前面再用一个负载均衡器如Nginx分发流量。这种基于微服务的设计使得每个组件都可以独立伸缩为未来的增长留足了空间。