Flask API部署Heroku后报500错误:model未定义问题求助
Flask API部署Heroku后出现500错误(NameError: model未定义)的解决方案
问题描述
本地运行正常的Flask API部署到Heroku后,调用/api/接口返回500内部服务器错误,Heroku日志显示NameError: name 'model' is not defined。原因是模型加载代码写在if __name__ == '__main__'代码块内,而Heroku使用gunicorn启动应用时不会执行该代码块,导致predict函数无法找到model变量。
相关代码与配置
应用代码
# Import libraries from flask import Flask, request import mlflow import numpy as np import pickle import os app = Flask(__name__) @app.route('/api/',methods=['POST']) def predict(): data = request.get_json() prediction = np.array2string(model.predict_proba(data)) return prediction if __name__ == '__main__': model = pickle.load(open('ModelGrid.sav', 'rb')) app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 5000)))
本地请求代码
url = 'http://localhost:8080/api/' data = New_Data.values.tolist() j_data = json.dumps(data) headers = {'content-type': 'application/json', 'Accept-Charset': 'UTF-8'} r = requests.post(url, data=j_data, headers=headers) result2 = float(r.text.split(' ')[1].split(']]')[0]) int(round(result2,2)*100)
线上请求代码
url = 'https://prediction-app-p7-6a2e12152edf.herokuapp.com/api/' data = New_Data.values.tolist() j_data = json.dumps(data) headers = {'content-type': 'application/json', 'Accept-Charset': 'UTF-8'} r = requests.post(url, data=j_data, headers=headers) result2 = float(r.text.split(' ')[1].split(']]')[0]) int(round(result2,2)*100)
GitHub配置
- Procfile:
web: gunicorn Flask:app - requirements.txt包含streamlit、pandas、Flask、gunicorn等依赖
- runtime.txt:
python-3.11.4
关键错误日志
NameError: name 'model' is not defined
解决方案
将模型加载代码移出if __name__ == '__main__'代码块,放到全局作用域中,确保gunicorn启动应用时能加载模型。修改后的应用代码如下:
# Import libraries from flask import Flask, request import mlflow import numpy as np import pickle import os app = Flask(__name__) # 全局加载模型,确保gunicorn启动时执行 model = pickle.load(open('ModelGrid.sav', 'rb')) @app.route('/api/',methods=['POST']) def predict(): data = request.get_json() prediction = np.array2string(model.predict_proba(data)) return prediction if __name__ == '__main__': app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 5000)))
额外注意事项
- 确保
ModelGrid.sav文件已正确上传到GitHub仓库,Heroku部署时能读取到该文件。 - 若模型文件较大,可考虑优化模型文件大小,或使用Heroku附加存储服务避免部署异常。
- 可在模型加载逻辑中添加异常处理,方便排查加载失败问题:
try: model = pickle.load(open('ModelGrid.sav', 'rb')) except Exception as e: print(f"模型加载失败: {str(e)}") raise
内容的提问来源于stack exchange,提问作者Rocheteau
相关产品推荐
相关产品推荐

