模型加载、输入规则和并发配置必须在编写第一行路由代码之前进行处理:模型需要顶层或lifespan一次性加载并存为全局变量;pydantic必须显式地声明字段顺序并转移到二维数组;Uvicorn必须设置workers并锁定sklearn版本。
能够跑步并不等于能够使用——FastAPI 启动后模型加载失败,高并发响应卡死,输入格式错误 ValueError: Expected 2D array,这三类问题占在线故障的比例 80% 以上。模型加载、输入规则和并发配置必须在编写第一行路由代码之前进行处理。
@app.post 里加载
每个请求都执行 joblib.load("model.pkl"),会导致内存持续上升,首次超响应 5 秒、多 worker 下模型重复加载甚至崩溃。
- 正确的做法:在
main.py顶层或lifespan一次性加载存在于全局变量中 - 若用 pipeline(含 scaler + clf),必须用
joblib.load()不要单独加载整个对象 load - 必须使用绝对路径或基于绝对路径
__file__结构应避免部署过程中工作目录的变化FileNotFoundError - 加日志确认加载成功:
logger.info(f"Loaded model with {model.n_estimators} trees")
Pydantic 必须覆盖输入验证 shape 和字段顺序
前端传 {"sepal_length": 5.1, "sepal_width": 3.5},但是模型训练的时列顺序是 ["sepal_length", "sepal_width", "petal_length", "petal_width"],直接转 list(dict.values()) 会错乱。
Python数据分析助手
为业务和科研数据的快速处理提供Python数据清理、统计分析和可视化建议。
下载- 定义
BaseModel显式声明字段名和顺序,如:class IrisInput(BaseModel): sepal_length: float; sepal_width: float; petal_length: float; petal_width: float - 在进入模型之前,强制转换为二维:
np.array([request.sepal_length, request.sepal_width, ...]).reshape(1, -1) - 数值范围用
Field(gt=0, lt=10)验证,防异常值直接进入模型 NaN 输出 - 别依赖
request.dict().values(),字典键的顺序是 Python 3.7+ 虽然插入顺序得到了保证,但很容易被重构损坏
Uvicorn 启动参数不调,--workers 就是摆设
默认单 worker 即使在模式下 CPU 有 8 核,所有请求也排队等模型实例——sklearn 推理的本质是同步阻塞,async 不要解决这个问题。
立即学习“Python免费学习笔记(深入);
- 生产必须加
--workers N,N 通常设为os.cpu_count()或其 1.5 倍(如 4 核机器设--workers 6) - 禁用
--reload:开发方便,但会触发多次模型加载,不能用于生产 - 加
--timeout-keep-alive 5防长连接堆积,加--limit-concurrency 100控制瞬时并发数 - 启动命令示例:
uvicorn app.main:app --workers 4 --host 0.0.0.0 --port 8000 --timeout-keep-alive 5
最容易被忽视的是模型版本和 sklearn 版本强绑定——joblib.load() 在 sklearn 1.4.2 训练模型,使用 1.5.0 加载高概率报告 AttributeError 或者预测结果是混乱的。上线前必须锁定 scikit-learn==1.4.2 并验证 predict 结果的一致性。