GLM-4-9B-Chat-1M模型服务化实践:REST API封装
1. 引言
大模型部署后如何让其他应用方便调用?这是很多开发者面临的实际问题。今天我们来聊聊如何将GLM-4-9B-Chat-1M这个强大的语言模型封装成REST API服务,让任何应用都能通过简单的HTTP请求来使用它的智能对话能力。
GLM-4-9B-Chat-1M支持高达1M的上下文长度,相当于约200万中文字符,这在处理长文档、复杂对话场景时特别有用。通过REST API封装,我们可以让Web应用、移动端、甚至是其他服务都能轻松集成这个强大的AI能力。
2. 环境准备与快速部署
2.1 基础环境要求
在开始之前,确保你的环境满足以下要求:
- Python 3.8+
- CUDA 11.8+(GPU推理)
- 至少24GB GPU显存(建议32GB以上)
- 足够的系统内存和存储空间
2.2 安装必要依赖
# 创建虚拟环境 python -m venv glm4-api-env source glm4-api-env/bin/activate # 安装核心依赖 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 pip install transformers>=4.44.0 pip install fastapi uvicorn pip install vllm # 可选,用于高性能推理2.3 模型下载
你可以从ModelScope或Hugging Face下载模型:
from modelscope import snapshot_download model_dir = snapshot_download('ZhipuAI/glm-4-9b-chat-1m')或者使用Hugging Face的Transformers直接加载:
from transformers import AutoModelForCausalLM, AutoTokenizer model_name = "THUDM/glm-4-9b-chat-1m" tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True) model = AutoModelForCausalLM.from_pretrained( model_name, torch_dtype=torch.bfloat16, device_map="auto", trust_remote_code=True )3. 基础API服务搭建
3.1 简单的FastAPI应用
我们先创建一个基础的API服务:
from fastapi import FastAPI, HTTPException from pydantic import BaseModel import torch from transformers import AutoModelForCausalLM, AutoTokenizer app = FastAPI(title="GLM-4-9B-Chat API") # 定义请求和响应模型 class ChatRequest(BaseModel): messages: list max_tokens: int = 1024 temperature: float = 0.7 class ChatResponse(BaseModel): response: str tokens_used: int # 加载模型(在实际应用中应该使用单例模式) @app.on_event("startup") async def load_model(): global model, tokenizer try: model_name = "THUDM/glm-4-9b-chat-1m" tokenizer = AutoTokenizer.from_pretrained( model_name, trust_remote_code=True ) model = AutoModelForCausalLM.from_pretrained( model_name, torch_dtype=torch.bfloat16, device_map="auto", trust_remote_code=True ) print("模型加载成功") except Exception as e: print(f"模型加载失败: {e}") @app.post("/chat", response_model=ChatResponse) async def chat_completion(request: ChatRequest): try: # 准备输入 inputs = tokenizer.apply_chat_template( request.messages, add_generation_prompt=True, tokenize=True, return_tensors="pt", return_dict=True ) # 生成配置 gen_kwargs = { "max_length": len(inputs['input_ids'][0]) + request.max_tokens, "do_sample": True, "temperature": request.temperature, "top_k": 50 } # 生成响应 with torch.no_grad(): outputs = model.generate(**inputs, **gen_kwargs) response_text = tokenizer.decode( outputs[0][len(inputs['input_ids'][0]):], skip_special_tokens=True ) return ChatResponse( response=response_text, tokens_used=len(outputs[0]) ) except Exception as e: raise HTTPException(status_code=500, detail=str(e)) if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)3.2 启动服务
保存为app.py后运行:
python app.py服务启动后,你可以在http://localhost:8000/docs查看自动生成的API文档。
4. 高性能优化方案
4.1 使用vLLM加速推理
对于生产环境,建议使用vLLM来获得更好的性能:
from vllm import LLM, SamplingParams from vllm.engine.arg_utils import AsyncEngineArgs from vllm.engine.async_llm_engine import AsyncLLMEngine import asyncio # 初始化vLLM引擎 engine_args = AsyncEngineArgs( model="THUDM/glm-4-9b-chat-1m", tensor_parallel_size=1, # 根据GPU数量调整 max_model_len=32768, # 根据显存调整 trust_remote_code=True, gpu_memory_utilization=0.9 ) llm_engine = AsyncLLMEngine.from_engine_args(engine_args) # 修改API端点使用vLLM @app.post("/v1/chat/completions") async def vllm_chat_completion(request: ChatRequest): try: # 准备prompt prompt = tokenizer.apply_chat_template( request.messages, tokenize=False, add_generation_prompt=True ) # 设置生成参数 sampling_params = SamplingParams( temperature=request.temperature, max_tokens=request.max_tokens, stop_token_ids=[151329, 151336, 151338] # GLM的特殊停止token ) # 生成响应 results = await llm_engine.generate( prompt, sampling_params, request_id="test" ) response_text = results[0].outputs[0].text return ChatResponse( response=response_text, tokens_used=len(results[0].outputs[0].token_ids) ) except Exception as e: raise HTTPException(status_code=500, detail=str(e))4.2 内存和性能优化
对于长文本处理,需要特别注意内存使用:
# 优化配置示例 optimized_args = AsyncEngineArgs( model="THUDM/glm-4-9b-chat-1m", tensor_parallel_size=2, # 2卡并行 max_model_len=65536, # 最大长度 gpu_memory_utilization=0.85, # 内存使用率 enable_chunked_prefill=True, # 启用分块预填充 max_num_batched_tokens=8192, # 批处理token数 trust_remote_code=True )5. 完整的生产级API服务
5.1 增强的API功能
一个生产级的API服务应该包含更多功能:
from fastapi import FastAPI, Depends, HTTPException from fastapi.middleware.cors import CORSMiddleware from contextlib import asynccontextmanager import time import logging # 配置日志 logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) # 生命周期管理 @asynccontextmanager async def lifespan(app: FastAPI): # 启动时加载模型 logger.info("正在加载模型...") await load_model() yield # 关闭时清理资源 logger.info("正在清理资源...") if 'llm_engine' in globals(): await llm_engine.engine.shutdown() app = FastAPI( title="GLM-4-9B-Chat API", lifespan=lifespan, version="1.0.0" ) # 添加CORS中间件 app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # 健康检查端点 @app.get("/health") async def health_check(): return {"status": "healthy", "timestamp": time.time()} # 带速率限制的聊天端点 from slowapi import Limiter from slowapi.util import get_remote_address limiter = Limiter(key_func=get_remote_address) @app.post("/v1/chat/completions") @limiter.limit("10/minute") # 每分钟10次请求 async def chat_completion( request: ChatRequest, request_id: str = None ): # 实现细节... pass5.2 错误处理和监控
from prometheus_fastapi_instrumentator import Instrumentator # 添加监控 Instrumentator().instrument(app).expose(app) # 自定义异常处理 @app.exception_handler(Exception) async def global_exception_handler(request, exc): logger.error(f"全局异常: {exc}") return JSONResponse( status_code=500, content={"error": "内部服务器错误"} )6. 客户端调用示例
6.1 Python客户端
import requests import json class GLMClient: def __init__(self, base_url="http://localhost:8000"): self.base_url = base_url def chat(self, messages, max_tokens=1024, temperature=0.7): payload = { "messages": messages, "max_tokens": max_tokens, "temperature": temperature } response = requests.post( f"{self.base_url}/v1/chat/completions", json=payload, headers={"Content-Type": "application/json"} ) if response.status_code == 200: return response.json() else: raise Exception(f"API调用失败: {response.text}") # 使用示例 client = GLMClient() response = client.chat([ {"role": "user", "content": "你好,请介绍一下你自己"} ]) print(response["response"])6.2 JavaScript客户端
async function callGLMAPI(messages) { const response = await fetch('http://localhost:8000/v1/chat/completions', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ messages: messages, max_tokens: 1024, temperature: 0.7 }) }); if (!response.ok) { throw new Error('API调用失败'); } return await response.json(); } // 使用示例 const messages = [ {role: "user", content: "写一个关于人工智能的短故事"} ]; callGLMAPI(messages) .then(response => console.log(response.response)) .catch(error => console.error(error));7. 部署和运维建议
7.1 Docker容器化部署
创建Dockerfile:
FROM python:3.10-slim WORKDIR /app # 安装系统依赖 RUN apt-get update && apt-get install -y \ git \ curl \ && rm -rf /var/lib/apt/lists/* # 复制依赖文件 COPY requirements.txt . RUN pip install -r requirements.txt # 复制应用代码 COPY . . # 暴露端口 EXPOSE 8000 # 启动命令 CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]7.2 性能监控和扩缩容
建议使用以下工具进行监控:
- Prometheus + Grafana:监控API性能和资源使用
- ELK Stack:日志收集和分析
- Kubernetes:容器编排和自动扩缩容
8. 总结
通过本文的实践,我们成功将GLM-4-9B-Chat-1M模型封装成了REST API服务。从基础的环境搭建到高性能优化,再到生产级的部署方案,我们覆盖了模型服务化的完整流程。
实际使用中发现,vLLM确实能显著提升推理性能,特别是在处理并发请求时。对于长文本场景,适当调整max_model_len和内存配置很重要。建议在生产环境中使用Docker容器化部署,并结合监控系统来确保服务稳定性。
这种API化的方式让GLM-4的强大能力能够被各种应用轻松集成,无论是Web应用、移动端还是其他微服务,都能通过简单的HTTP调用来获得智能对话功能。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。