You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI(Uvicorn部署)性能优化及POST接口低RPS问题排查

问题根源分析
  1. 异步接口中的同步阻塞逻辑:你用async def定义了POST接口,但detectron2与PaddleOCR的推理是同步CPU/GPU绑定操作,这类代码会直接阻塞Uvicorn worker的单线程事件循环——每个worker在处理POST请求时,会被同步推理代码占死,无法再处理其他请求。这就是调整worker数量(1-8)对POST接口RPS提升有限的核心原因:即使增加worker,每个worker依然只能串行处理POST请求,GPU/CPU资源利用率可能并未拉满。
  2. 资源瓶颈未匹配并发策略:POST接口的推理是重计算任务,需要检查GPU利用率(用nvidia-smi实时查看):
    • 如果GPU利用率始终处于低位,说明worker的并发逻辑没有让GPU同时处理多个推理任务;
    • 如果GPU利用率已接近100%,则单请求的推理耗时(1.7-4秒)就是吞吐量的天花板,需要从模型优化入手。
  3. 异步定义的误用:async def仅适用于IO密集型场景(如数据库查询、HTTP请求),对于计算密集的模型推理,异步语法无法带来性能提升,反而可能增加事件循环的调度开销。
吞吐量优化方案

1. 剥离同步推理任务,避免阻塞事件循环

将同步的推理代码放到线程池/进程池中执行,让Uvicorn的事件循环能同时处理多个请求:

from fastapi import FastAPI, UploadFile
import asyncio
from concurrent.futures import ThreadPoolExecutor
# 导入你的detectron2和PaddleOCR依赖
from your_inference_module import run_inference

app = FastAPI()
# 根据GPU并发能力设置线程池大小,比如GPU支持8个并行推理任务则设为8-10
executor = ThreadPoolExecutor(max_workers=8)

def sync_infer_task(file_content: bytes):
    # 同步执行模型推理
    return run_inference(file_content)

@app.post("/detect")
async def detect(file: UploadFile):
    content = await file.read()
    # 将同步任务提交到线程池,不阻塞事件循环
    result = await asyncio.to_thread(sync_infer_task, content)
    return {"result": result}

如果推理任务是CPU密集且受GIL限制,可替换为ProcessPoolExecutor,但需要注意进程间数据传输的开销。

2. 优化模型推理性能

  • 模型优化:用TensorRT、ONNX Runtime对detectron2和PaddleOCR模型做量化、算子融合,减少单请求的推理耗时;
  • 流水线并行:将预处理、推理、后处理三个阶段拆分为独立的异步任务,让多个请求的不同阶段并行执行;
  • 批量处理:如果业务允许接受一定延迟,可攒集多个请求做批量推理,提升GPU资源利用率。

3. 调整部署配置

  • Uvicorn worker数量:保持在CPU核心数的1-2倍(你的12核机器设为8符合限制);
  • 线程池大小:根据GPU的并发处理能力调整,确保能同时向GPU提交多个推理任务,避免GPU闲置。
生产环境部署方案选择
  • 若仅需处理FastAPI接口+模型推理,Uvicorn完全可以作为生产级部署方案,核心是解决同步阻塞问题即可;
  • 若模型推理是核心业务,且需要更精细化的资源调度、批处理、模型版本管理,可考虑专门的模型推理框架(如Ray Serve、TorchServe、PaddleServing),这些框架针对GPU资源优化,能更高效地提升推理吞吐量。

内容的提问来源于stack exchange,提问作者Kiran Roy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 18:20:03