尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

基于FastAPI与LiteLLM构建统一多模型推理服务:从本地Ollama到云端API

基于FastAPI与LiteLLM构建统一多模型推理服务:从本地Ollama到云端API 1. 项目概述为什么要把本地模型搬到线上最近几个月我身边不少搞AI应用开发的朋友都在琢磨同一件事自己用Ollama在本地跑通了大模型效果不错成本也低但怎么才能让团队里的其他人、或者自己开发的应用也能方便地用上呢总不能给每个人都装一套Ollama吧。这个需求催生了一个很实际的工程问题如何把本地玩转的模型平滑地迁移到一个可以对外提供服务的线上环境里。我这次折腾的目标很明确就是搭建一个多模型推理服务Multi-Model Runtime让它不仅能继续服务我本地常用的模型还能无缝接入像DeepSeek、Qwen这类需要API密钥的云端大模型。这样一来我的应用后端只需要对接这一个统一的接口就能根据场景灵活调用本地模型省成本或者调用云端模型求效果架构上清爽多了。这不仅仅是“部署一个服务”那么简单。它涉及到几个核心挑战协议的统一如何让不同来源的模型都通过同一种方式对话、管理的便捷如何轻松地启停、切换模型、以及成本的优化如何在本地算力和云端API开销间做权衡。这次实战复盘我就把从Ollama本地部署到构建线上多模型Runtime的完整过程包括踩过的坑和最终验证可行的方案详细拆解一遍。无论你是想给自己做的AI工具加个后端还是想为小团队提供一个内部分享的模型服务这套思路应该都能给你提供直接的参考。2. 核心架构设计与技术选型在动手敲代码之前花点时间把架构想清楚能省去后面无数返工的麻烦。我们的目标是构建一个“模型路由网关”它本身不负责具体的模型推理而是作为一个智能调度层。2.1 核心需求拆解首先得明确这个Runtime需要干什么统一API接口无论底层是本地Ollama的模型还是DeepSeek的API对上游应用比如你的聊天机器人、知识库系统来说调用的方式应该是一样的。最通用的就是兼容OpenAI API格式因为生态工具最丰富。多模型管理服务需要知道当前有哪些模型可用每个模型对应什么后端本地 or 云端以及它们的配置如API密钥、基础URL。路由与转发收到请求后能根据请求中的模型名称如qwen:7b或deepseek-chat将请求体正确转发到对应的后端服务并将响应返回。配置化与热更新增加或移除一个模型最好不需要重启服务通过修改配置文件就能生效。轻量与易部署服务本身应该足够轻资源消耗小易于通过Docker等方式部署。2.2 技术方案选型为什么是 FastAPI LiteLLM市面上有几种实现路径路径一直接魔改 Ollama API Server。Ollama本身提供了API但它的设计重点是管理本地模型。要让它去代理转发第三方API改动成本高且会破坏其简洁性。路径二从零开始写一个代理网关。用Flask或FastAPI接收请求然后根据模型名用requests库去调用不同后端。这是最直接但也最“糙”的方法需要自己处理错误重试、流式响应、上下文管理等一系列繁琐问题。路径三使用专业的模型抽象层框架。这就是我选择的LiteLLM。它不是一个完整的服务而是一个Python库其核心价值在于将数十家不同厂商的模型APIOpenAI, Anthropic, Cohere, 以及阿里云、DeepSeek等统一成了OpenAI的格式。选择LiteLLM的理由非常充分省时省力它已经完美解决了最棘手的协议适配问题。调用DeepSeek和调用本地Ollama在你的代码里看起来几乎一样。功能完整原生支持流式响应Streaming、异步调用、聊天上下文管理、计算token消耗对于控制API成本至关重要等高级功能。配置驱动模型配置可以通过一个YAML文件或环境变量来管理符合“配置化”的需求。社区活跃项目更新快遇到问题相对容易找到解决方案。因此最终架构确定为使用FastAPI作为Web框架快速构建RESTful接口使用LiteLLM作为核心模型调用与抽象层使用Uvicorn或Gunicorn作为ASGI服务器进行生产部署。这个组合在灵活性和开发效率之间取得了很好的平衡。2.3 基础环境准备我的开发环境是Ubuntu 22.04但以下步骤在macOS和WSL2上也是类似的。首先确保你的机器上已经安装了Python建议3.9以上和Ollama。# 1. 创建并进入项目目录 mkdir multi-model-runtime cd multi-model-runtime # 2. 创建虚拟环境强烈推荐避免包冲突 python -m venv venv source venv/bin/activate # Linux/macOS # venv\Scripts\activate # Windows # 3. 安装核心依赖 pip install fastapi uvicorn litellmlitellm这一个包就包含了我们对接多模型后端所需的所有核心逻辑。接下来我们验证一下Ollama本地服务是否正常。# 启动Ollama服务如果还没启动的话 ollama serve # 拉取一个测试模型比如小巧的Qwen2.5:0.5B ollama pull qwen2.5:0.5b-instruct # 在另一个终端测试模型是否可用 ollama run qwen2.5:0.5b-instruct “你好”如果能看到模型回复说明本地Ollama基础环境就绪。3. 从零构建多模型Runtime服务环境准备好后我们就可以开始编写核心服务代码了。我会按照功能模块一步步构建这个服务。3.1 构建统一的FastAPI应用骨架首先创建一个main.py文件这是服务的入口。# main.py from fastapi import FastAPI, HTTPException from fastapi.responses import StreamingResponse import litellm from litellm import completion from pydantic import BaseModel from typing import List, Optional import os import yaml import logging # 配置日志方便调试 logging.basicConfig(levellogging.INFO) logger logging.getLogger(__name__) # 初始化FastAPI应用 app FastAPI(titleMulti-Model Runtime API, version1.0.0) # 定义请求数据模型兼容OpenAI ChatCompletion格式 class ChatMessage(BaseModel): role: str # “system”, “user”, “assistant” content: str class ChatCompletionRequest(BaseModel): model: str # 这是关键用于路由到具体模型如 “ollama/qwen2.5:0.5b” 或 “deepseek-chat” messages: List[ChatMessage] stream: Optional[bool] False max_tokens: Optional[int] None temperature: Optional[float] 0.7 # 全局模型配置字典将从配置文件加载 model_config {}这个骨架定义了Web服务的基础和最重要的请求数据结构。注意ChatCompletionRequest中的model字段它将是我们实现路由的关键。3.2 设计并加载模型配置文件我们不希望把API密钥、模型映射关系等硬编码在代码里。最佳实践是使用一个配置文件。创建一个config.yaml文件# config.yaml model_config: # 本地Ollama模型配置 “ollama/qwen2.5:0.5b-instruct”: model_name: “qwen2.5:0.5b-instruct” # Ollama内部的模型名 litellm_params: model: “ollama/qwen2.5:0.5b-instruct” # LiteLLM识别的模型标识符 api_base: “http://localhost:11434 # Ollama服务地址 api_key: “not-needed” # Ollama不需要key但LiteLLM要求有该字段 # 云端DeepSeek模型配置 “deepseek-chat”: litellm_params: model: “deepseek-chat” api_key: “${DEEPSEEK_API_KEY}” # 从环境变量读取安全 api_base: “https://api.deepseek.com # DeepSeek API端点 # 可以继续添加其他模型例如通义千问 “qwen-plus”: litellm_params: model: “qwen-plus” api_key: “${DASHSCOPE_API_KEY}” # 阿里云灵积的API Key api_base: “https://dashscope.aliyuncs.com/compatible-mode/v1 # 服务配置 runtime: host: “0.0.0.0” port: 8000这个配置文件的精妙之处在于模型标识符作为键我们自定义了ollama/qwen2.5:0.5b-instruct这样的字符串作为模型ID。上游应用就使用这个ID来指定调用哪个模型。LiteLLM参数映射litellm_params下的内容会直接传递给LiteLLM的completion函数。LiteLLM会根据model字段的值如ollama/...或deepseek-chat自动选择正确的适配器。环境变量注入使用${VAR_NAME}语法避免将敏感信息提交到代码仓库。接下来在main.py中添加配置加载函数# main.py (续) def load_config(config_path: str “config.yaml”): “”“加载并解析配置文件”“” global model_config try: with open(config_path, ‘r’, encoding‘utf-8’) as f: raw_config yaml.safe_load(f) # 处理环境变量替换 resolved_config {} for model_id, config in raw_config.get(‘model_config’, {}).items(): resolved_params {} for key, value in config.get(‘litellm_params’, {}).items(): if isinstance(value, str) and value.startswith(‘${’) and value.endswith(‘}’): env_var value[2:-1] resolved_params[key] os.environ.get(env_var, “”) # 从环境变量读取 if not resolved_params[key]: logger.warning(f“环境变量 {env_var} 未设置用于模型 {model_id}”) else: resolved_params[key] value # 将处理后的配置存入全局字典 model_config[model_id] {“litellm_params”: resolved_params} logger.info(f“成功加载 {len(model_config)} 个模型配置。”) return raw_config.get(‘runtime’, {}) except FileNotFoundError: logger.error(f“配置文件 {config_path} 未找到。”) raise except Exception as e: logger.error(f“加载配置文件时出错: {e}”) raise # 在应用启动时加载配置 runtime_config load_config()3.3 实现核心的聊天补全接口现在实现最关键的路由逻辑。我们将创建一个/v1/chat/completions端点这是OpenAI兼容的标准接口。# main.py (续) app.post(“/v1/chat/completions”) async def create_chat_completion(request: ChatCompletionRequest): “”“ 统一的聊天补全接口。 根据request.model字段路由到对应的后端模型。 “”“ model_id request.model logger.info(f“收到请求模型ID: {model_id}, 流式: {request.stream}”) # 1. 检查请求的模型是否在配置中 if model_id not in model_config: raise HTTPException(status_code404, detailf“模型 ‘{model_id}’ 未配置或不可用。”) # 2. 获取该模型的LiteLLM参数 config model_config[model_id][“litellm_params”] logger.debug(f“使用配置: {config}”) # 3. 准备调用参数 completion_kwargs { “model”: model_id, # LiteLLM会利用这个和config[‘model’]进行内部映射 “messages”: [msg.dict() for msg in request.messages], “stream”: request.stream, } # 添加可选参数 if request.max_tokens is not None: completion_kwargs[“max_tokens”] request.max_tokens if request.temperature is not None: completion_kwargs[“temperature”] request.temperature # 4. 关键步骤使用LiteLLM进行调用并注入特定模型的配置 try: # litellm.completion 支持直接传入 api_base, api_key 等参数 # 我们将模型专属配置与通用参数合并 response await completion(**{**completion_kwargs, **config}) except Exception as e: logger.error(f“调用模型 {model_id} 时出错: {e}”, exc_infoTrue) # LiteLLM抛出的异常通常包含详细错误信息可以提取并返回给用户 error_detail str(e) raise HTTPException(status_code500, detailf“模型服务调用失败: {error_detail}”) # 5. 处理响应流式和非流式 if request.stream: # 流式响应处理 async def stream_generator(): try: async for chunk in response: # LiteLLM的流式响应chunk已经是OpenAI兼容格式 yield f“data: {chunk.model_dump_json()}\n\n” yield “data: [DONE]\n\n” except Exception as e: logger.error(f“流式响应生成失败: {e}”) yield f“data: {‘error’: {‘message’: ‘Stream interrupted’}}\n\n” return StreamingResponse(stream_generator(), media_type“text/event-stream”) else: # 非流式响应直接返回 return response.model_dump()这个函数是整个服务的“大脑”。它做了以下几件事路由通过model_id从全局配置中取出对应模型的专属参数API密钥、Base URL。适配将这些专属参数和通用的请求参数合并一起传给litellm.completion。代理LiteLLM库会根据model字段和api_base等参数自动决定是调用本地Ollama的HTTP接口还是去请求DeepSeek的云端API。统一返回将LiteLLM返回的响应无论是来自Ollama还是DeepSeek封装成统一的OpenAI格式返回给客户端。3.4 添加模型列表与健康检查接口一个好的API服务还需要一些辅助接口。# main.py (续) app.get(“/v1/models”) async def list_models(): “”“返回当前已配置的所有可用模型列表。”“” models_list [] for model_id, config in model_config.items(): # 这里可以添加更多模型元信息如拥有者、权限等 model_info { “id”: model_id, “object”: “model”, “created”: 1686935000, # 示例时间戳 “owned_by”: “runtime”, } models_list.append(model_info) return {“object”: “list”, “data”: models_list} app.get(“/health”) async def health_check(): “”“服务健康检查端点。”“” # 这里可以添加对Ollama服务等下游依赖的检查 return {“status”: “healthy”, “service”: “multi-model-runtime”} # 启动服务 if __name__ “__main__”: import uvicorn host runtime_config.get(“host”, “0.0.0.0”) port runtime_config.get(“port”, 8000) uvicorn.run(app, hosthost, portport)4. 配置、运行与测试服务代码写好了接下来就是让它跑起来并验证功能。4.1 配置环境变量与启动服务首先设置DeepSeek等云端模型的API密钥。# 在终端中设置环境变量临时重启后失效 export DEEPSEEK_API_KEY“your_deepseek_api_key_here” export DASHSCOPE_API_KEY“your_dashscope_api_key_here” # 更推荐的做法是使用 .env 文件 # 创建 .env 文件 echo “DEEPSEEK_API_KEYyour_deepseek_api_key_here” .env echo “DASHSCOPE_API_KEYyour_dashscope_api_key_here” .env # 使用 python-dotenv 在代码中加载需先 pip install python-dotenv # 或在启动服务前 source .env然后启动我们的多模型Runtime服务# 确保在项目虚拟环境中 source venv/bin/activate # 启动服务 python main.py你应该能看到类似下面的输出表明服务已在http://localhost:8000启动INFO: Started server process [12345] INFO: Waiting for application startup. INFO: Application startup complete. INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRLC to quit) INFO: 成功加载 3 个模型配置。4.2 使用curl进行功能测试让我们用最直接的curl命令来测试接口是否工作。测试1调用本地Ollama的Qwen模型curl http://localhost:8000/v1/chat/completions \ -H “Content-Type: application/json” \ -d ‘{ “model”: “ollama/qwen2.5:0.5b-instruct”, “messages”: [{“role”: “user”, “content”: “用一句话介绍你自己。”}], “temperature”: 0.7 }’如果成功你会收到一个JSON响应其中choices[0].message.content字段包含了模型的回答。测试2调用云端DeepSeek模型curl http://localhost:8000/v1/chat/completions \ -H “Content-Type: application/json” \ -d ‘{ “model”: “deepseek-chat”, “messages”: [{“role”: “user”, “content”: “你好请写一首关于春天的五言绝句。”}], “temperature”: 0.8 }’这个请求会被我们的服务转发到DeepSeek的官方API并返回结果。注意这里我们请求体里的model字段是deepseek-chat而不是DeepSeek API可能要求的某个具体模型名。模型名称的映射和转换完全由LiteLLM和我们的配置文件在底层处理了对客户端是透明的。测试3测试流式响应流式响应对于需要实时显示生成结果的场景如聊天界面至关重要。curl -N http://localhost:8000/v1/chat/completions \ -H “Content-Type: application/json” \ -d ‘{ “model”: “ollama/qwen2.5:0.5b-instruct”, “messages”: [{“role”: “user”, “content”: “给我讲一个程序员的笑话。”}], “stream”: true }’使用-N参数禁用缓冲你将会看到一系列以data:开头的Server-Sent Events (SSE)数据块被实时推送回来。测试4获取模型列表curl http://localhost:8000/v1/models这个接口会返回我们在config.yaml中配置的所有模型上游应用可以动态获取可用的模型列表。4.3 使用OpenAI SDK进行集成测试由于我们的API是OpenAI兼容的这意味着你可以直接使用官方的openaiPython库或者JavaScript库来调用你自己的服务这极大地简化了客户端集成。# test_client.py from openai import OpenAI # 注意这里的基础URL指向我们自己的服务API Key可以填任意非空字符串因为我们本地Ollama不需要 client OpenAI( base_url“http://localhost:8000/v1”, # 指向我们的Runtime api_key“not-needed” # 对于不需要鉴权的本地模型这个字段需要存在但内容任意 ) # 调用本地模型 response client.chat.completions.create( model“ollama/qwen2.5:0.5b-instruct”, messages[{“role”: “user”, “content”: “什么是机器学习”}], streamFalse ) print(“本地模型回复:”, response.choices[0].message.content) # 调用云端模型需要配置正确的API_KEY环境变量 client_cloud OpenAI( base_url“http://localhost:8000/v1”, api_key“not-needed” # 这里填任意值因为真正的密钥在服务端配置里 ) # 注意对于云端模型服务端会使用config中的api_key客户端的api_key参数在此时仅作为占位符 response_cloud client_cloud.chat.completions.create( model“deepseek-chat”, messages[{“role”: “user”, “content”: “解释一下Transformer架构。”}], streamFalse ) print(“云端模型回复:”, response_cloud.choices[0].message.content)运行这个测试脚本你会看到它能成功调用两个不同后端的模型。这就是统一API接口的魅力所在客户端代码无需任何修改只需改变model参数就能切换不同的模型提供商。5. 生产环境部署与优化建议让服务在本地跑起来只是第一步。要用于生产环境还需要考虑稳定性、可维护性和性能。5.1 使用Gunicorn提升并发能力开发时用的uvicorn main:app适合调试但对于生产环境我们通常配合Gunicorn作为进程管理器。pip install gunicorn # 使用gunicorn启动指定worker数量通常为CPU核心数*21 gunicorn -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000 main:appGunicorn会管理多个工作进程提高服务的并发处理能力避免单个进程被阻塞导致整个服务无响应。5.2 Docker容器化部署容器化是保证环境一致性和便捷部署的最佳实践。创建一个Dockerfile# Dockerfile FROM python:3.11-slim WORKDIR /app # 复制依赖文件并安装 COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt # 复制应用代码和配置文件 COPY . . # 暴露端口 EXPOSE 8000 # 设置环境变量生产环境建议通过docker run -e或编排工具注入 # ENV DEEPSEEK_API_KEY... # 启动命令使用gunicorn CMD [“gunicorn”, “-w”, “4”, “-k”, “uvicorn.workers.UvicornWorker”, “-b”, “0.0.0.0:8000”, “main:app”]同时创建一个requirements.txt文件fastapi0.104.1 uvicorn[standard]0.24.0 litellm1.20.2 pyyaml6.0.1 gunicorn21.2.0 python-dotenv1.0.0然后构建并运行镜像docker build -t multi-model-runtime . docker run -p 8000:8000 --env-file .env multi-model-runtime5.3 配置热更新与模型管理我们之前的设计模型配置是在服务启动时加载的。如果想实现不重启服务就增删模型需要增加一个动态配置管理接口。可以在main.py中增加一个管理端点注意在生产环境要加鉴权# main.py (续) - 管理端点示例 from fastapi import Security from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials security HTTPBearer() # 一个简单的密钥验证生产环境应用更安全的方案如JWT ADMIN_TOKEN os.environ.get(“ADMIN_TOKEN”, “your-super-secret-token”) def verify_admin(credentials: HTTPAuthorizationCredentials Security(security)): if credentials.credentials ! ADMIN_TOKEN: raise HTTPException(status_code403, detail“无效的管理员令牌”) app.post(“/admin/model”, dependencies[Depends(verify_admin)]) async def add_or_update_model(model_id: str, config: dict): “”“动态添加或更新模型配置需要管理员权限”“” # 这里需要验证config结构然后更新 model_config 字典 # 注意对于LiteLLM某些参数可能需要在litellm模块内也进行更新 model_config[model_id] config logger.info(f“模型 {model_id} 配置已更新。”) return {“status”: “success”, “model_id”: model_id}这样你就可以通过一个授权的API调用来动态管理模型了。不过更常见的做法是将配置存储在数据库或配置中心如Consul服务定时拉取或监听变更。5.4 监控、日志与限流对于一个生产服务这些都是必不可少的监控使用Prometheus采集指标请求量、延迟、错误率用Grafana展示。可以通过prometheus-fastapi-instrumentator中间件轻松集成。日志配置更结构化的日志JSON格式并输出到标准输出方便被Docker或K8s的日志收集器如Fluentd抓取。限流使用slowapi或fastapi-limiter为不同API端点或模型设置速率限制防止滥用或意外的高成本API调用。超时与重试在调用LiteLLM时为不同的后端设置不同的超时时间。对于云端API可以考虑增加重试逻辑注意对非幂等操作要小心。6. 常见问题与排查技巧实录在实际搭建和运行过程中我遇到了不少问题。这里把典型问题和解决方法记录下来希望能帮你绕过这些坑。6.1 连接Ollama服务失败问题现象调用本地Ollama模型时服务返回500错误日志显示连接被拒绝(ConnectionRefusedError)或超时。排查步骤确认Ollama服务状态在终端执行ollama serve看它是否在运行并监听在11434端口。可以用curl http://localhost:11434/api/tags测试。检查网络配置如果你的Runtime服务运行在Docker容器内而Ollama运行在宿主机那么容器内不能使用localhost来访问宿主机。在Linux上通常使用host.docker.internalDocker Desktop或宿主机IP如172.17.0.1。需要修改config.yaml中的api_base。防火墙/安全组检查宿主机防火墙是否屏蔽了11434端口。实操心得在Docker Compose编排时将Ollama和Runtime服务定义在同一个自定义网络下然后通过服务名如ollama:11434进行通信是最清晰稳定的方式。6.2 调用云端API返回认证错误问题现象调用DeepSeek或通义千问时返回401 Unauthorized或Invalid API Key。排查步骤环境变量确认确保在运行Runtime服务的环境终端、Docker容器、K8s Pod中正确设置了DEEPSEEK_API_KEY等环境变量。可以用echo $DEEPSEEK_API_KEY检查。配置文件解析检查config.yaml中${VAR_NAME}的语法是否正确变量名是否拼写错误。API密钥有效性直接使用curl命令测试你的API密钥是否有效。例如对于DeepSeekcurl https://api.deepseek.com/chat/completions \ -H ‘Content-Type: application/json’ \ -H ‘Authorization: Bearer YOUR_DEEPSEEK_API_KEY’ \ -d ‘{“model”: “deepseek-chat”, “messages”: [{“role”: “user”, “content”: “hi”}]}’如果这里也失败说明密钥本身有问题或者账户欠费、被禁用。LiteLLM版本有时不同版本的LiteLLM对某些云厂商API的支持有细微差别。查看LiteLLM的官方文档和Issue确认你使用的版本是否支持该厂商。6.3 流式响应不工作或格式错误问题现象客户端设置了stream: true但收不到数据流或者收到的是非SSE格式的完整响应。排查步骤检查服务端日志确认请求是否以流式模式处理。日志中应有流式: True的提示。验证LiteLLM流式支持不是所有LiteLLM支持的后端都完美支持流式。首先用非流式调用确认基础功能正常。客户端处理方式确保客户端正确处理了SSE格式。数据应该是data: {...}\n\n格式并以data: [DONE]\n\n结束。使用curl -N测试是最直接的。FastAPI中间件干扰某些自定义的FastAPI中间件可能会缓冲响应破坏流式。检查是否添加了全局的响应处理中间件。6.4 性能瓶颈分析与优化问题表现服务响应慢尤其是调用本地大模型时。优化方向Ollama模型加载Ollama在首次调用一个模型时需要加载耗时较长。可以考虑在服务启动后用一个预热脚本提前加载常用模型ollama run model_name。Runtime服务本身使用gunicorn配合多个worker进程可以并行处理多个请求。但注意如果worker数超过CPU核心数可能会因上下文切换导致性能下降。硬件资源本地推理的性能瓶颈通常在GPU如果有或CPU/内存。使用nvidia-smi或htop监控资源使用情况。对于CPU推理确保Ollama使用了正确的BLAS后端如OpenBLAS、oneDNN并设置了合适的线程数通过OMP_NUM_THREADS环境变量。请求排队如果并发请求数超过worker数请求会排队。对于耗时的模型推理需要考虑引入更复杂的任务队列如Celery和结果缓存机制。6.5 配置管理混乱问题表现模型多了之后config.yaml文件变得庞大且难以维护。解决方案按环境分离配置创建config.dev.yaml,config.prod.yaml通过环境变量APP_ENV决定加载哪个。使用配置中心对于微服务架构将配置存入Consul、Etcd或云服务商的密钥管理服务如AWS SSM Parameter Store, Azure Key Vault。Runtime服务启动时或定期从配置中心拉取。数据库存储将模型配置存入数据库如PostgreSQL并提供一个管理界面进行CRUD操作。服务监听配置变更事件或定期轮询更新。7. 进阶玩法与扩展思路基础的多模型Runtime搭建完成后你可以根据实际需求进行很多有趣的扩展。7.1 实现负载均衡与故障转移如果你有多个同型号的GPU服务器都运行了Ollama可以在配置中为一个模型ID配置多个后端地址并在Runtime中实现简单的轮询或随机负载均衡。# config.yaml 扩展 “ollama/llama3:8b”: litellm_params: model: “ollama/llama3:8b” api_base: [“http://gpu-server-1:11434, “http://gpu-server-2:11434] api_key: “not-needed” strategy: “round-robin” # 自定义字段供你的路由逻辑使用然后在main.py的调用逻辑中根据strategy从api_base列表中选取一个地址。你还可以加入简单的健康检查自动剔除故障的后端。7.2 集成模型缓存层对于内容生成类应用相同的提示词可能被多次请求。可以集成一个缓存层如Redis将(model_id, messages, parameters)的哈希值作为键将完整的响应作为值存储起来。下次收到相同请求时直接返回缓存结果极大降低响应延迟和计算/API成本。注意这需要根据业务场景判断是否可行例如对于聊天历史缓存可能不适用。7.3 增加计费与用量统计如果你需要向团队内部或外部用户收费就需要统计每个用户、每个模型的Token使用量。LiteLLM的响应对象里包含了usage字段如prompt_tokens,completion_tokens。你可以在FastAPI的中间件中拦截响应解析这个字段并记录到数据库中。对于按Token计费的云端模型这个功能至关重要。7.4 构建模型能力评估与自动路由这是更智能的玩法。你可以为每个模型打上能力标签如擅长代码、长上下文、低成本。当上游应用发来请求时可以携带一些元数据如required_skills: [“coding”],budget: “low”由Runtime服务根据这些标签和实时负载自动选择最合适的模型进行调用实现智能路由。整个项目从构思到实现最深的体会是“抽象”的力量。LiteLLM库为我们抽象了不同模型API的差异而我们的Runtime服务则在此基础上抽象出了一个统一的模型调用层。这让客户端应用彻底从复杂的模型对接中解放出来只需要关心业务逻辑。后续的维护成本也主要集中在模型配置的管理和Runtime服务本身的稳定性上而不是为每一个新模型去重写一遍对接代码。这种架构对于快速迭代的AI应用开发来说效率提升是巨大的。
返回列表