Flask启动模型API只需三步:初始化时加载模型为全局变量、定义POST预测接口并规范处理JSON输入为二维数组与float64类型、用gunicorn部署并添加输入校验、超时控制和健康检查端点。

用Flask快速启动一个模型API服务
直接跑通最简可用的模型API,核心就三步:加载模型、定义预测接口、启动服务。别碰FastAPI或Docker先,90%的内部验证需求用Flask加几行代码就能搞定。
常见错误是把joblib.load()写在路由函数里——每次请求都反序列化一次模型,延迟飙升。必须在应用初始化时加载一次,存为全局变量:
from flask import Flask, request, jsonify
import joblib
<p>app = Flask(<strong>name</strong>)
model = joblib.load("model.pkl") # ← 这里加载,不是在 predict() 里</p><p>@app.route("/predict", methods=["POST"])
def predict():
data = request.get_json()
X = [data["features"]] # 假设输入是 {"features": [1.2, 3.4, 0.8]}
y_pred = model.predict(X).tolist()
return jsonify({"prediction": y_pred})运行:flask run --host=0.0.0.0 --port=5000,然后用curl -X POST http://localhost:5000/predict -H "Content-Type: application/json" -d '{"features": [1.2, 3.4, 0.8]}'测试。
处理scikit-learn的输入形状与数据类型问题
模型训练时用numpy.ndarray,但API收到的是JSON,request.get_json()返回的是Python原生list或dict,直接喂给model.predict()大概率报ValueError: Expected 2D array, got 1D array instead。
立即学习“Python免费学习笔记(深入)”;
必须显式转成二维结构,并统一数值类型:
- 单样本预测:用
np.array(data["features"]).reshape(1, -1),不能只套一层[...](嵌套list不等于2D array) - 多样本预测:检查输入是否为
list of list,再转np.array(...),否则[[1,2], [3,4]]可能被误判为一维 - 强制类型转换:
.astype(np.float64),避免JSON解析后出现int或float32导致sklearn内部校验失败
绕过pickle兼容性陷阱:别用默认joblib版本保存模型
joblib.dump(model, "model.pkl")在不同Python或scikit-learn版本间极易失效,常见报错:ModuleNotFoundError: No module named 'sklearn.ensemble._forest' 或 AttributeError: 'RandomForestClassifier' object has no attribute 'n_features_in_' 。
安全做法只有两个:
- 部署环境严格锁定
scikit-learn版本,比如pip install scikit-learn==1.3.0,且保存模型时用同一版本 - 改用
sklearn.utils._testing.assert_all_finite等底层工具不依赖的格式——实际更可靠的是用onnx(需skl2onnx)或纯Python重实现预测逻辑(仅限简单模型如LogisticRegression)
临时调试可加异常捕获并打印model.__dict__.keys(),确认关键属性是否存在,比如n_features_in_在0.22+才稳定支持。
生产环境必须加的三道防线
本地能跑不等于能上线。没加这三项,模型API大概率在真实流量下崩:
- 输入校验:用
pydantic或手写if len(data.get("features", [])) != model.n_features_in_:,拒绝非法长度特征,别让predict()抛出晦涩错误 - 超时控制:
app.run(..., threaded=True)只是开发模式,生产必须用gunicorn --workers 2 --timeout 30 app:app,防止慢请求拖垮整个进程 - 健康检查端点:
@app.route("/health")返回{"status": "ok", "model_loaded": True},供K8s或负载均衡器探测
模型输入维度、scikit-learn版本、Web服务器并发模型——这三个点任何一个对不上,API就会静默失败或返回错误结果,比崩溃更难排查。


















