通义千问3-Reranker-0.6B实战指南:与FastAPI集成构建RESTful rerank微服务
通义千问3-Reranker-0.6B实战指南:与FastAPI集成构建RESTful rerank微服务
1. 项目概述
通义千问3-Reranker-0.6B是Qwen3 Embedding模型系列中的重排序专用模型,专门设计用于文本相关性排序任务。这个6亿参数的模型在保持轻量级的同时,提供了出色的多语言支持和长文本理解能力。
在实际应用中,我们经常需要将这样的AI模型集成到现有的系统中,而Gradio界面虽然友好,但更适合演示和测试。通过FastAPI构建RESTful微服务,我们可以获得更好的性能、更灵活的部署方式,以及更易于集成的API接口。
本文将手把手教你如何将Qwen3-Reranker-0.6B模型与FastAPI框架集成,构建一个生产级的重排序微服务。
2. 环境准备与依赖安装
2.1 基础环境要求
首先确保你的系统满足以下要求:
# Python版本要求
Python >= 3.8 (推荐Python 3.10)
PyTorch >= 2.0.0
Transformers >= 4.51.0
2.2 安装必要依赖
创建并激活虚拟环境后,安装所需依赖:
# 创建虚拟环境
python -m venv qwen3-reranker-env
source qwen3-reranker-env/bin/activate # Linux/Mac
# 或者 .\qwen3-reranker-env\Scripts\activate # Windows
# 安装核心依赖
pip install torch>=2.0.0 --index-url https://download.pytorch.org/whl/cu118
pip install transformers>=4.51.0
pip install fastapi>=0.104.0
pip install uvicorn>=0.24.0
pip install pydantic>=2.0.0
pip install accelerate>=0.24.0
pip install safetensors>=0.4.0
3. FastAPI服务核心代码实现
3.1 创建主应用文件
新建一个app.py文件,包含完整的FastAPI服务代码:
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List, Optional
import torch
from transformers import AutoModelForSequenceClassification, AutoTokenizer
import logging
import time
# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
app = FastAPI(
title="Qwen3-Reranker-0.6B API",
description="基于FastAPI的文本重排序微服务",
version="1.0.0"
)
class RerankRequest(BaseModel):
query: str
documents: List[str]
instruction: Optional[str] = None
batch_size: Optional[int] = 8
top_k: Optional[int] = None
class RerankResponse(BaseModel):
results: List[dict]
processing_time: float
# 全局变量存储模型和tokenizer
model = None
tokenizer = None
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
@app.on_event("startup")
async def load_model():
"""启动时加载模型"""
global model, tokenizer
try:
logger.info("开始加载Qwen3-Reranker-0.6B模型...")
start_time = time.time()
model_path = "/root/ai-models/Qwen/Qwen3-Reranker-0___6B"
# 加载tokenizer和模型
tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)
model = AutoModelForSequenceClassification.from_pretrained(
model_path,
torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
device_map="auto",
trust_remote_code=True
)
model.eval()
load_time = time.time() - start_time
logger.info(f"模型加载完成,耗时: {load_time:.2f}秒")
logger.info(f"使用设备: {device}")
except Exception as e:
logger.error(f"模型加载失败: {str(e)}")
raise
def rerank_documents(query: str, documents: List[str], instruction: Optional[str] = None, batch_size: int = 8):
"""执行重排序的核心函数"""
if model is None or tokenizer is None:
raise HTTPException(status_code=503, detail="模型未加载完成")
if not documents:
return []
# 构建输入对
pairs = []
for doc in documents:
if instruction:
text_pair = f"{instruction}\nQuery: {query}\nDocument: {doc}"
else:
text_pair = f"Query: {query}\nDocument: {doc}"
pairs.append(text_pair)
# 批量处理
results = []
for i in range(0, len(pairs), batch_size):
batch_pairs = pairs[i:i + batch_size]
# tokenize
inputs = tokenizer(
batch_pairs,
padding=True,
truncation=True,
max_length=32768,
return_tensors="pt"
).to(device)
# 推理
with torch.no_grad():
outputs = model(**inputs)
scores = outputs.logits[:, 0].cpu().numpy()
# 收集结果
for j, score in enumerate(scores):
doc_index = i + j
if doc_index < len(documents):
results.append({
"document": documents[doc_index],
"score": float(score),
"rank": 0 # 后续统一排序
})
# 按分数排序
results.sort(key=lambda x: x["score"], reverse=True)
# 添加排名
for rank, result in enumerate(results, 1):
result["rank"] = rank
return results
@app.post("/rerank", response_model=RerankResponse)
async def rerank_endpoint(request: RerankRequest):
"""重排序API端点"""
start_time = time.time()
try:
# 验证输入
if not request.query:
raise HTTPException(status_code=400, detail="查询文本不能为空")
if not request.documents:
raise HTTPException(status_code=400, detail="文档列表不能为空")
if len(request.documents) > 100:
raise HTTPException(status_code=400, detail="单次最多处理100个文档")
# 执行重排序
results = rerank_documents(
query=request.query,
documents=request.documents,
instruction=request.instruction,
batch_size=request.batch_size
)
# 应用top_k过滤
if request.top_k and request.top_k > 0:
results = results[:request.top_k]
processing_time = time.time() - start_time
return RerankResponse(
results=results,
processing_time=processing_time
)
except Exception as e:
logger.error(f"处理请求时出错: {str(e)}")
raise HTTPException(status_code=500, detail=f"处理失败: {str(e)}")
@app.get("/health")
async def health_check():
"""健康检查端点"""
return {
"status": "healthy",
"model_loaded": model is not None,
"device": str(device)
}
@app.get("/")
async def root():
"""根端点,返回API信息"""
return {
"message": "Qwen3-Reranker-0.6B API服务",
"version": "1.0.0",
"endpoints": {
"rerank": "POST /rerank - 执行文本重排序",
"health": "GET /health - 服务健康检查"
}
}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
3.2 创建配置文件
新建config.py文件用于配置管理:
import os
from typing import Optional
class Config:
# 模型配置
MODEL_PATH: str = os.getenv("MODEL_PATH", "/root/ai-models/Qwen/Qwen3-Reranker-0___6B")
DEVICE: str = os.getenv("DEVICE", "auto")
BATCH_SIZE: int = int(os.getenv("BATCH_SIZE", "8"))
# 服务配置
HOST: str = os.getenv("HOST", "0.0.0.0")
PORT: int = int(os.getenv("PORT", "8000"))
WORKERS: int = int(os.getenv("WORKERS", "1"))
# 性能配置
MAX_DOCUMENTS: int = int(os.getenv("MAX_DOCUMENTS", "100"))
TIMEOUT: int = int(os.getenv("TIMEOUT", "300"))
# 日志配置
LOG_LEVEL: str = os.getenv("LOG_LEVEL", "INFO")
config = Config()
4. 部署与运行指南
4.1 启动FastAPI服务
有多种方式可以启动你的重排序服务:
方式一:直接运行Python脚本
python app.py
方式二:使用Uvicorn启动(推荐)
# 开发模式(带热重载)
uvicorn app:app --reload --host 0.0.0.0 --port 8000
# 生产模式(多worker)
uvicorn app:app --host 0.0.0.0 --port 8000 --workers 2 --timeout-keep-alive 300
4.2 创建启动脚本
创建start_fastapi.sh启动脚本:
#!/bin/bash
# Qwen3-Reranker FastAPI服务启动脚本
# 设置环境变量
export MODEL_PATH="/root/ai-models/Qwen/Qwen3-Reranker-0___6B"
export BATCH_SIZE=8
export PORT=8000
export WORKERS=1
# 激活虚拟环境
source /root/Qwen3-Reranker-0.6B/venv/bin/activate
# 启动服务
echo "启动Qwen3-Reranker FastAPI服务..."
uvicorn app:app --host 0.0.0.0 --port $PORT --workers $WORKERS
# 如果使用GPU,可以添加CUDA相关设置
# export CUDA_VISIBLE_DEVICES=0
给脚本添加执行权限并运行:
chmod +x start_fastapi.sh
./start_fastapi.sh
5. API使用示例
5.1 Python客户端调用示例
创建client_example.py文件:
import requests
import json
from typing import List, Optional
class QwenRerankerClient:
def __init__(self, base_url: str = "http://localhost:8000"):
self.base_url = base_url.rstrip('/')
def rerank(self,
query: str,
documents: List[str],
instruction: Optional[str] = None,
batch_size: int = 8,
top_k: Optional[int] = None) -> dict:
"""
调用重排序API
Args:
query: 查询文本
documents: 候选文档列表
instruction: 自定义指令(可选)
batch_size: 批处理大小
top_k: 返回前K个结果
Returns:
API响应结果
"""
payload = {
"query": query,
"documents": documents,
"instruction": instruction,
"batch_size": batch_size,
"top_k": top_k
}
try:
response = requests.post(
f"{self.base_url}/rerank",
json=payload,
timeout=30
)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"API调用失败: {e}")
return None
# 使用示例
if __name__ == "__main__":
client = QwenRerankerClient()
# 示例1:英文查询
english_result = client.rerank(
query="What is the capital of China?",
documents=[
"Beijing is the capital of China.",
"Gravity is a force that attracts two bodies towards each other.",
"The sky appears blue because of Rayleigh scattering."
],
instruction="Given a web search query, retrieve relevant passages that answer the query"
)
print("英文查询结果:")
print(json.dumps(english_result, indent=2, ensure_ascii=False))
# 示例2:中文查询
chinese_result = client.rerank(
query="解释量子力学",
documents=[
"量子力学是物理学的一个分支,主要研究微观粒子的运动规律。",
"今天天气很好,适合外出游玩。",
"苹果是一种常见的水果,富含维生素。"
],
top_k=2 # 只返回前2个结果
)
print("\n中文查询结果:")
print(json.dumps(chinese_result, indent=2, ensure_ascii=False))
5.2 命令行调用示例
使用curl命令测试API:
# 健康检查
curl http://localhost:8000/health
# 重排序请求
curl -X POST "http://localhost:8000/rerank" \
-H "Content-Type: application/json" \
-d '{
"query": "What is machine learning?",
"documents": [
"Machine learning is a subset of artificial intelligence.",
"The Eiffel Tower is in Paris, France.",
"ML algorithms build models based on sample data."
],
"batch_size": 4,
"top_k": 2
}'
6. 性能优化与最佳实践
6.1 批处理大小优化
根据你的硬件配置调整批处理大小:
# GPU内存充足(8GB+)
BATCH_SIZE = 16
# GPU内存一般(4-8GB)
BATCH_SIZE = 8
# GPU内存较小或使用CPU
BATCH_SIZE = 4
6.2 自定义指令模板
为不同场景提供优化指令:
INSTRUCTION_TEMPLATES = {
"web_search": "Given a web search query, retrieve relevant passages that answer the query",
"legal": "Given a legal query, retrieve relevant legal documents and provisions",
"academic": "Given an academic query, retrieve relevant research papers and articles",
"code": "Given a code-related query, retrieve relevant code snippets and documentation",
"general": "Given a query, retrieve the most relevant documents from the candidate set"
}
6.3 异步处理支持
对于高并发场景,可以考虑使用异步处理:
@app.post("/async-rerank")
async def async_rerank_endpoint(request: RerankRequest):
"""异步重排序端点(适用于高并发)"""
# 将任务提交到线程池执行
loop = asyncio.get_event_loop()
result = await loop.run_in_executor(
None, # 使用默认线程池
lambda: rerank_documents(
request.query,
request.documents,
request.instruction,
request.batch_size
)
)
return {"results": result}
7. 监控与维护
7.1 添加性能监控
集成Prometheus监控:
from prometheus_fastapi_instrumentator import Instrumentator
# 添加性能监控
Instrumentator().instrument(app).expose(app)
7.2 日志配置优化
创建更详细的日志配置:
import logging
from logging.config import dictConfig
log_config = {
"version": 1,
"formatters": {
"default": {
"format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
}
},
"handlers": {
"console": {
"class": "logging.StreamHandler",
"formatter": "default",
"level": "INFO"
},
"file": {
"class": "logging.handlers.RotatingFileHandler",
"formatter": "default",
"filename": "reranker_service.log",
"maxBytes": 10485760, # 10MB
"backupCount": 5,
"level": "INFO"
}
},
"root": {
"handlers": ["console", "file"],
"level": "INFO"
}
}
dictConfig(log_config)
8. 总结
通过本文的实战指南,你已经学会了如何将Qwen3-Reranker-0.6B模型与FastAPI框架集成,构建一个生产级的重排序微服务。相比原始的Gradio界面,FastAPI版本提供了:
- 更好的性能:支持批处理、异步处理
- 更灵活的API:RESTful接口,易于集成
- 更强的稳定性:错误处理、健康检查、监控
- 更高的可配置性:支持自定义指令、批处理大小调整
这种集成方式特别适合需要将重排序能力嵌入到现有系统的场景,比如搜索引擎、推荐系统、问答系统等。FastAPI的自动文档生成功能(访问 http://localhost:8000/docs)也让API的使用和测试变得更加方便。
记得根据你的实际需求调整配置参数,特别是批处理大小和硬件配置,以达到最佳的性能效果。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。
更多推荐
所有评论(0)