FastAPI加载SavedModel报错:文件不存在问题求助
问题描述
我在FastAPI服务中加载SavedModel时遇到报错,模型文件和Python代码都在./server/routes目录下。执行启动命令:
uvicorn main:app --reload
出现错误提示:
SavedModel file does not exist at: saved_model.pb/{saved_model.pbtxt|saved_model.pb}.
相关FastAPI代码如下:
import os import tensorflow as tf from fastapi import FastAPI, UploadFile, File from fastapi.responses import JSONResponse import numpy as np import cv2 app = FastAPI() model_path = '/home/sharif/Desktop/Ekunjo-A-Gardening-Solution/server/routes/saved_model.pb' model = tf.saved_model.load("saved_model.pb") @app.post("/predict") async def predict_image(file: UploadFile = File(...)): contents = await file.read() # Convert the image to a format compatible with the model nparr = np.fromstring(contents, np.uint8) img = cv2.imdecode(nparr, cv2.IMREAD_COLOR) img = cv2.resize(img, (224, 224)) img = img / 255.0 # Normalize the image # Make predictions input_data = np.expand_dims(img, axis=0) # Adding a batch dimension prediction = model.signatures["serving_default"](tf.constant(input_data))["dense"].numpy() # Return the prediction result return JSONResponse(content={"prediction": prediction.tolist()})
问题原因
- 模型路径参数错误:
tf.saved_model.load()要求传入的是包含SavedModel文件的目录路径,而非单个saved_model.pb文件的路径。TensorFlow会自动在指定目录下查找saved_model.pb或saved_model.pbtxt,你直接传单个文件路径,它会试图在这个文件路径下再找模型文件,自然找不到。 - 路径逻辑不一致:代码里定义了
model_path变量却没使用,反而用了相对路径saved_model.pb,如果启动服务时的工作目录不是./server/routes,相对路径会指向错误位置。
解决步骤
- 确认SavedModel结构完整性:正常的SavedModel是一个目录,结构如下:
如果只有单个saved_model_dir/ ├── saved_model.pb └── variables/ ├── variables.data-00000-of-00001 └── variables.indexsaved_model.pb文件,说明这不是完整的SavedModel,需要重新导出完整模型。 - 修正模型加载路径:
- 如果模型目录和代码在同一目录,直接用目录名作为路径,比如模型目录叫
my_saved_model,就写tf.saved_model.load("my_saved_model"); - 或者用绝对路径,利用定义好的变量(注意要指向目录,不是单个文件):
model = tf.saved_model.load(model_path)
model_path是单个文件路径,要改成目录路径,比如/home/sharif/Desktop/Ekunjo-A-Gardening-Solution/server/routes/my_saved_model。 - 如果模型目录和代码在同一目录,直接用目录名作为路径,比如模型目录叫
- 确保服务启动目录正确:如果用相对路径,要在
./server/routes目录下执行启动命令,或者用--app-dir参数指定目录:uvicorn main:app --reload --app-dir ./server/routes
修改后的代码示例
import os import tensorflow as tf from fastapi import FastAPI, UploadFile, File from fastapi.responses import JSONResponse import numpy as np import cv2 app = FastAPI() # 替换成你的模型目录绝对路径 model_dir = '/home/sharif/Desktop/Ekunjo-A-Gardening-Solution/server/routes/my_saved_model' # 或者用相对路径(需确保启动服务时工作目录正确) # model_dir = 'my_saved_model' # 传入模型目录路径加载 model = tf.saved_model.load(model_dir) @app.post("/predict") async def predict_image(file: UploadFile = File(...)): contents = await file.read() # 转换图像格式适配模型 nparr = np.fromstring(contents, np.uint8) img = cv2.imdecode(nparr, cv2.IMREAD_COLOR) img = cv2.resize(img, (224, 224)) img = img / 255.0 # 图像归一化 # 执行预测 input_data = np.expand_dims(img, axis=0) # 添加批次维度 prediction = model.signatures["serving_default"](tf.constant(input_data))["dense"].numpy() return JSONResponse(content={"prediction": prediction.tolist()})
内容的提问来源于stack exchange,提问作者SharifMAbdullah
相关产品推荐
相关产品推荐

