尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

第48课:TensorFlow|TF模型线上部署入门【本地服务封装、接口快速开发】

第48课:TensorFlow|TF模型线上部署入门【本地服务封装、接口快速开发】 文章目录1. 课前导读1.1 本节课学习目标1.2 知识重难点1.3 学习前置条件1.4 学完可掌握能力1.5 行业应用场景2. 核心理论精讲2.1 模型服务的架构模式2.2 模型导出与优化2.3 服务框架选型2.4 批处理与合并请求2.5 容器化部署2.6 监控与日志3. 环境搭建与工具配置3.1 安装依赖3.2 准备预训练模型4. 代码实战教学4.1 使用FastAPI创建同步推理API4.2 异步批处理队列高级4.3 使用TensorFlow Serving部署4.4 使用Docker封装FastAPI服务4.5 性能测试使用locust5. 案例实操演练5.1 模型准备5.2 FastAPI服务增强5.3 部署到云服务示例AWS Lambda 不适合大模型建议ECS5.4 压力测试与结果分析6. 常见坑点与排错总结6.1 模型加载与签名6.2 性能问题6.3 并发与稳定性6.4 TensorFlow Serving坑点7. 知识点总结 课后作业7.1 核心知识点梳理7.2 基础作业7.3 进阶实操作业7.4 思考拓展题《TensorFlow2.x: 深度学习入门到高阶实战教程》系列课程导航1. 课前导读1.1 本节课学习目标理解线上模型服务的需求与挑战延迟、吞吐量、扩展性。掌握将Keras模型导出为优化后的SavedModel支持批量推理。学会使用FastAPI构建轻量级高性能API服务包括同步和异步端点。实现批处理与请求合并动态batching提高GPU利用率。了解TensorFlow Serving的安装与基本使用实现模型版本管理。掌握使用Docker打包模型服务实现环境一致性。通过实战案例图像分类服务完成从模型导出到服务启动的全过程。1.2 知识重难点类别内容重点SavedModel导出与签名定义FastAPI路由与请求处理批处理推理优化TensorFlow Serving的部署与调用难点动态批处理的请求队列管理异步处理与WebSocketTensorFlow Serving的gRPC客户端编写Docker镜像优化减小体积易混淆点REST vs gRPC同步API vs 异步API模型签名中的输入输出名称TensorFlow Serving的模型版本策略1.3 学习前置条件已完成第20课模型保存与加载熟悉SavedModel。能够训练简单的CNN模型。了解Python Web框架基础和Docker概念可选。1.4 学完可掌握能力独立将模型封装为REST API提供稳定推理服务。使用FastAPI实现高并发接口。使用TensorFlow Serving进行企业级模型部署。容器化模型服务便于迁移和扩展。1.5 行业应用场景在线图像识别手机APP调用云端API。推荐系统实时获取用户推荐。金融反欺诈低延迟评分服务。IoT边缘计算在边缘节点部署模型服务。2. 核心理论精讲2.1 模型服务的架构模式模型服务通常以HTTP/REST或gRPC协议对外提供API。客户端发送请求图像、文本等服务端进行预处理、模型推理、后处理返回结果。架构要点无状态每个请求独立便于水平扩展。高并发利用异步IO、线程池、动态批处理。可观测日志、监控、链路追踪。2.2 模型导出与优化训练后的模型Keras H5或SavedModel需要导出为优化格式。推荐使用SavedModel它包含图结构和权重支持跨语言。优化手段静态图转换tf.function提前编译。量化INT8量化减小体积和加速需评估精度损失。移除训练相关操作如Dropout、BatchNormalization的统计。导出代码tf.saved_model.save(model,model/1,signatures...)# 版本号子目录2.3 服务框架选型框架特点适用场景Flask轻量、简单低并发、原型验证FastAPI异步、高性能、自动文档高并发、生产级APIgRPC二进制协议、低延迟、多语言内部微服务调用TensorFlow Serving专为TF模型设计版本管理、批处理大规模生产部署本课重点使用FastAPI因其易用性和性能和TensorFlow Serving。2.4 批处理与合并请求深度学习推理在批量处理时效率更高GPU并行。若请求是随机到达的单个样本服务端可将多个请求合并为一个批次称为动态批处理。实现方式使用队列收集请求等待固定时间或积累到一定数量。调用模型批量推理将结果返回给各个请求。TensorFlow Serving内置了动态批处理功能--enable_batching。2.5 容器化部署Docker封装模型服务确保环境一致性和快速部署。Dockerfile示例FROM tensorflow/serving:2.13.0 COPY ./model /models/my_model ENV MODEL_NAMEmy_model然后使用docker run启动。2.6 监控与日志生产服务需记录请求数量、延迟分布、错误率。模型版本、硬件资源使用。使用Prometheus Grafana或云服务。3. 环境搭建与工具配置3.1 安装依赖conda activate tf213 pipinstallfastapi uvicorn[standard]python-multipart pillow tensorflow-serving-api安装Docker可选用于TensorFlow Serving容器。3.2 准备预训练模型我们使用一个简单的MNIST CNN模型训练并导出为SavedModel。importtensorflowastffromtensorflowimportkerasfromtensorflow.kerasimportlayers# 训练简单CNN(x_train,y_train),(x_test,y_test)keras.datasets.mnist.load_data()x_trainx_train.reshape(-1,28,28,1).astype(float32)/255.0x_testx_test.reshape(-1,28,28,1).astype(float32)/255.0modelkeras.Sequential([layers.Conv2D(32,3,activationrelu,input_shape(28,28,1)),layers.MaxPooling2D(),layers.Conv2D(64,3,activationrelu),layers.Flatten(),layers.Dense(10,activationsoftmax)])model.compile(optimizeradam,losssparse_categorical_crossentropy,metrics[accuracy])model.fit(x_train,y_train,epochs3,batch_size128,validation_split0.1)# 导出为SavedModel定义签名tf.function(input_signature[tf.TensorSpec(shape[None,28,28,1],dtypetf.float32,nameinput)])defserve_fn(x):return{output:model(x)}model.save(mnist_model/1,signatures{serving_default:serve_fn})验证SavedModelsaved_model_cli show--dirmnist_model/1--all4. 代码实战教学4.1 使用FastAPI创建同步推理API# app.pyimporttensorflowastfimportnumpyasnpfromfastapiimportFastAPI,File,UploadFile,HTTPExceptionfromPILimportImageimportio appFastAPI(titleMNIST Classifier API)# 加载模型modeltf.saved_model.load(mnist_model/1)infermodel.signatures[serving_default]defpreprocess_image(image_bytes):imgImage.open(io.BytesIO(image_bytes)).convert(L)imgimg.resize((28,28))img_arraynp.array(img,dtypenp.float32)/255.0img_arrayimg_array.reshape(1,28,28,1)returnimg_arrayapp.post(/predict)asyncdefpredict(file:UploadFileFile(...)):try:contentsawaitfile.read()input_tensorpreprocess_image(contents)outputinfer(tf.constant(input_tensor))predictionsoutput[output].numpy()[0]digitint(np.argmax(predictions))confidencefloat(np.max(predictions))return{digit:digit,confidence:confidence}exceptExceptionase:raiseHTTPException(status_code400,detailstr(e))# 健康检查app.get(/health)asyncdefhealth():return{status:ok}if__name____main__:importuvicorn uvicorn.run(app,host0.0.0.0,port8000)启动服务python app.py测试请求curl-XPOST-Ffiletest.pnghttp://localhost:8000/predict4.2 异步批处理队列高级为了充分利用GPU可以实现请求队列合并多个请求为一个批次。下面是一个简单的批处理服务器使用asyncio队列。importasyncioimportthreadingimportqueueimporttimefromfastapiimportFastAPI,BackgroundTasksfrompydanticimportBaseModel app_batchFastAPI()request_queuequeue.Queue()response_dict{}defbatch_processor():后台线程处理批次whileTrue:time.sleep(0.1)# 等待积累请求batch_requests[]whilenotrequest_queue.empty()andlen(batch_requests)32:reqrequest_queue.get()batch_requests.append(req)ifbatch_requests:# 合并图像imagesnp.array([req[image]forreqinbatch_requests])predsinfer(tf.constant(images))[output].numpy()forreq,predinzip(batch_requests,preds):response_dict[req[id]]{digit:int(np.argmax(pred)),confidence:float(np.max(pred))}threading.Thread(targetbatch_processor,daemonTrue).start()app_batch.post(/predict_batch)asyncdefpredict_batch(file:UploadFile):importuuid req_idstr(uuid.uuid4())contentsawaitfile.read()input_tensorpreprocess_image(contents)[0]# 去掉batch维request_queue.put({id:req_id,image:input_tensor})# 轮询等待结果timeout5starttime.time()whilereq_idnotinresponse_dict:iftime.time()-starttimeout:raiseHTTPException(status_code504,detailTimeout)awaitasyncio.sleep(0.01)resultresponse_dict.pop(req_id)returnresult4.3 使用TensorFlow Serving部署启动TensorFlow Serving Docker容器dockerrun-t--rm-p8501:8501-v$(pwd)/mnist_model:/models/mnist-eMODEL_NAMEmnist tensorflow/serving:2.13.0然后使用REST API调用curl-d{instances: [[[[0.0]*28]*28]]}-XPOST http://localhost:8501/v1/models/mnist:predict或者gRPC客户端importgrpcimporttensorflowastffromtensorflow_serving.apisimportpredict_pb2,prediction_service_pb2_grpcimportnumpyasnp channelgrpc.insecure_channel(localhost:8500)stubprediction_service_pb2_grpc.PredictionServiceStub(channel)requestpredict_pb2.PredictRequest()request.model_spec.namemnistrequest.model_spec.signature_nameserving_defaultinput_tensortf.make_tensor_proto(np.random.rand(1,28,28,1).astype(np.float32))request.inputs[input].CopyFrom(input_tensor)responsestub.Predict(request,timeout10.0)print(response.outputs[output])4.4 使用Docker封装FastAPI服务编写DockerfileFROM python:3.9-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . CMD [uvicorn, app:app, --host, 0.0.0.0, --port, 8000]requirements.txttensorflow2.13.0 fastapi0.100.0 uvicorn[standard]0.23.0 pillow9.5.0 python-multipart0.0.6构建并运行dockerbuild-tmnist-api.dockerrun-p8000:8000 mnist-api4.5 性能测试使用locust安装locustpip install locust编写locustfile.pyfromlocustimportHttpUser,task,betweenimportrandomclassMNISTUser(HttpUser):wait_timebetween(1,2)taskdefpredict(self):withopen(sample.png,rb)asf:self.client.post(/predict,files{file:f})启动locust -f locustfile.py --hosthttp://localhost:80005. 案例实操演练案例部署一个商品分类模型ResNet50微调并提供API5.1 模型准备假设我们已经微调了ResNet50输出类别为5种商品。导出为SavedModel输入尺寸224×224×3。# 导出签名tf.function(input_signature[tf.TensorSpec(shape[None,224,224,3],dtypetf.float32)])defpredict_fn(x):return{probs:model(x)}tf.saved_model.save(model,product_model/1,signatures{serving_default:predict_fn})5.2 FastAPI服务增强添加多类别返回、日志记录、请求限流使用慢速。fromslowapiimportLimiter,_rate_limit_exceeded_handlerfromslowapi.utilimportget_remote_address limiterLimiter(key_funcget_remote_address)app.state.limiterlimiter app.add_exception_handler(429,_rate_limit_exceeded_handler)app.post(/predict)limiter.limit(10/minute)asyncdefpredict(request:Request,file:UploadFileFile(...)):# ... 同前5.3 部署到云服务示例AWS Lambda 不适合大模型建议ECS本课不展开云部署但可提及。5.4 压力测试与结果分析使用wrk或locust记录QPS和延迟。6. 常见坑点与排错总结6.1 模型加载与签名坑1加载SavedModel后直接调用模型失败需使用签名。解决model tf.saved_model.load(path); infer model.signatures[serving_default]。坑2输入张量名称与签名不匹配调用时出现KeyError。解决查看签名输入名称print(infer.structured_input_signature)。6.2 性能问题坑3单个请求推理慢未使用批处理。解决实现动态批处理或使用TensorFlow Serving内置批处理。坑4GPU利用率低服务成为CPU瓶颈。解决确保预处理图像解码、缩放在CPU上高效模型推理在GPU上使用异步并发。6.3 并发与稳定性坑5高并发下模型加载多次每个worker进程加载一份内存溢出。解决使用全局单例模型gunicorn使用--preload。坑6请求体过大导致内存爆炸。解决限制上传文件大小使用流式读取。6.4 TensorFlow Serving坑点坑7模型版本路径必须包含数字子目录否则无法识别。坑8gRPC客户端与REST端口混淆REST:8501, gRPC:8500。7. 知识点总结 课后作业7.1 核心知识点梳理模型导出SavedModel 签名定义。服务框架FastAPI高性能、异步、TensorFlow Serving专业模型服务。性能优化动态批处理、模型量化、并发控制。容器化Docker打包服务便于部署。监控日志、健康检查、压力测试。7.2 基础作业使用FastAPI部署MNIST模型并实现一个简单的前端页面调用API可用HTML表单。使用TensorFlow Serving部署同一模型通过REST API测试。用locust对API进行并发测试记录不同并发下的平均延迟。7.3 进阶实操作业任务实现支持文本分类的服务含预处理训练或使用预训练文本分类模型如IMDb情感分析。导出模型包含文本向量化层。构建FastAPI服务接收原始文本字符串返回情感类别和概率。实现请求限流和批量处理可选。使用Docker部署并编写docker-compose.yml管理服务和数据库可选。7.4 思考拓展题在分布式环境中如何保证模型服务的高可用和负载均衡如果模型推理延迟很高如1秒如何设计API以提升用户体验例如异步任务队列TensorFlow Serving与FastAPI TF模型直接调用相比有哪些优势和不足下一课预告项目性能调优全方案——我们将学习训练和推理的性能调优技巧包括数据加载优化、混合精度、XLA编译等榨干硬件性能。《TensorFlow2.x: 深度学习入门到高阶实战教程》系列课程导航去订阅第一部分基础入门1-10 课第二部分神经网络核心11-25 课第三部分进阶网络与框架高阶26-40 课第四部分企业实战与项目落地41-50 课 感谢您耐心阅读到这里 如果本文对您有所启发欢迎 点赞 收藏 分享给更多需要的伙伴。️ 期待在评论区看到您的想法, 共同进步。 关注我持续获取更多干货内容 我们下篇文章见
返回列表