GPEN如何集成到Web应用?Flask接口封装实战教程
你是否已经用过GPEN人像修复增强模型,但还停留在命令行运行阶段?想不想让你的AI能力被更多人使用,甚至嵌入到网页或App里?今天我们就来干一件更酷的事——把GPEN模型封装成一个Web API,通过Flask快速搭建一个可调用的服务接口,真正实现“模型即服务”。
本文面向有一定Python基础、了解过深度学习推理流程,但还没尝试过模型部署的同学。我们将手把手带你完成从本地推理脚本到Web服务的完整封装过程,最终实现:上传一张照片,返回修复后的人像结果。整个过程无需前端知识,纯后端实战,适合快速验证和集成。
1. 准备工作:理解GPEN镜像环境
在开始封装之前,先确认你的运行环境符合要求。本文基于以下预置镜像环境展开:
| 组件 | 版本 |
|---|---|
| 核心框架 | PyTorch 2.5.0 |
| CUDA 版本 | 12.4 |
| Python 版本 | 3.11 |
| 推理代码位置 | /root/GPEN |
该镜像已预装所有必要依赖:
facexlib: 负责人脸检测与对齐basicsr: 支持图像超分处理opencv-python,numpy<2.0,datasets==2.21.0,pyarrow==12.0.1sortedcontainers,addict,yapf
并且模型权重已提前下载至:
~/.cache/modelscope/hub/iic/cv_gpen_image-portrait-enhancement包含生成器、人脸检测器和对齐模型,支持离线推理,开箱即用。
1.1 激活环境并测试原始推理
首先激活Conda环境并进入项目目录:
conda activate torch25 cd /root/GPEN运行默认测试命令,验证模型是否正常工作:
python inference_gpen.py如果成功执行,你会在当前目录看到输出文件output_Solvay_conference_1927.png,说明模型可以正常加载和推理。
2. 封装目标:构建Flask Web API
我们的目标是创建一个简单的HTTP服务,提供如下功能:
- 接收用户上传的图片(POST请求)
- 使用GPEN模型进行人像修复
- 返回修复后的图片(Base64编码或直接返回二进制流)
最终调用方式将像这样:
curl -X POST http://localhost:5000/restore \ -F "image=@./my_photo.jpg" \ > restored.jpg2.1 安装Flask
虽然镜像中未预装Flask,但我们可以通过pip轻松安装:
pip install flask flask-cors pillow注意:
Pillow用于图像处理,flask-cors用于解决跨域问题,便于后续前端调用。
3. 核心代码改造:从脚本到函数化调用
原生的inference_gpen.py是为命令行设计的,我们需要将其改造成可导入的函数模块。
3.1 提取核心推理逻辑
我们新建一个文件gpen_service.py,并将关键推理流程封装为函数。
# gpen_service.py import os import cv2 import numpy as np from basicsr.utils import imwrite from facexlib.utils.face_restoration_helper import FaceRestoreHelper from torchvision.transforms.functional import normalize from models.gpen_model import FullGenerator import torch from PIL import Image import io class GPENRestorer: def __init__(self, model_path='weights/ffhq_generator_v1_8x.pth', size=512): self.device = torch.device('cuda' if torch.cuda.is_available() else 'cpu') self.size = size # 初始化人脸辅助工具 self.face_helper = FaceRestoreHelper( upscale_factor=1, face_size=size, crop_ratio=(1, 1), det_model='retinaface_resnet50', save_ext='png', use_parse=True, device=self.device ) # 加载生成器 self.net = FullGenerator( size, 512, 8, channel_multiplier=2, narrow=1, style_dim=512 ).to(self.device) ckpt = torch.load(model_path, map_location='cpu') self.net.load_state_dict(ckpt['g_ema']) self.net.eval() def process_image(self, input_img): """输入PIL.Image,返回修复后的PIL.Image""" # 转为OpenCV格式 img = cv2.cvtColor(np.array(input_img), cv2.COLOR_RGB2BGR) # 人脸检测与对齐 self.face_helper.clean_all() self.face_helper.read_image(img) self.face_helper.get_face_landmarks_5(only_center_face=True) self.face_helper.align_warp_face() restored_faces = [] for cropped_face in self.face_helper.cropped_faces: # 预处理 face_tensor = torch.from_numpy(cropped_face.transpose(2, 0, 1)).float() / 255. normalize(face_tensor, (0.5, 0.5, 0.5), (0.5, 0.5, 0.5), inplace=True) face_tensor = face_tensor.unsqueeze(0).to(self.device) try: with torch.no_grad(): output_face = self.net(face_tensor, return_latents=False)[0] # 后处理 output_face = (output_face * 0.5 + 0.5).clamp(0, 1) output_face = output_face.cpu().numpy().transpose(1, 2, 0) * 255 output_face = cv2.cvtColor(output_face.astype('uint8'), cv2.COLOR_BGR2RGB) restored_faces.append(output_face) except Exception as e: print(f"修复失败: {e}") restored_faces.append(cropped_face) # 合成回原图 self.face_helper.add_restored_face(restored_faces[0]) # 简化:只处理第一张脸 self.face_helper.restore_crop() self.face_helper.blend_faces() # 获取最终图像 result_img = self.face_helper.paste_faces_to_input_image() result_img = cv2.cvtColor(result_img, cv2.COLOR_BGR2RGB) return Image.fromarray(result_img)说明:这里我们简化了多脸处理逻辑,仅处理主脸。实际生产中可根据需求扩展。
4. 构建Flask服务接口
接下来创建app.py文件,启动Web服务。
# app.py from flask import Flask, request, send_file, jsonify from flask_cors import CORS from gpen_service import GPENRestorer from PIL import Image import numpy as np import io app = Flask(__name__) CORS(app) # 允许跨域请求 # 初始化模型(启动时加载一次) restorer = GPENRestorer(model_path='/root/.cache/modelscope/hub/iic/cv_gpen_image-portrait-enhancement/weights/ffhq_generator_v1_8x.pth') @app.route('/health', methods=['GET']) def health_check(): return jsonify({'status': 'ok', 'model_loaded': True}) @app.route('/restore', methods=['POST']) def restore_image(): if 'image' not in request.files: return jsonify({'error': 'No image uploaded'}), 400 file = request.files['image'] if file.filename == '': return jsonify({'error': 'Empty filename'}), 400 try: # 读取图像 input_img = Image.open(file.stream) # 执行修复 restored_img = restorer.process_image(input_img) # 转为字节流返回 img_io = io.BytesIO() restored_img.save(img_io, format='JPEG', quality=95) img_io.seek(0) return send_file(img_io, mimetype='image/jpeg', as_attachment=True, download_name='restored.jpg') except Exception as e: return jsonify({'error': str(e)}), 500 if __name__ == '__main__': app.run(host='0.0.0.0', port=5000, debug=False)4.1 接口说明
GET /health:健康检查,返回服务状态POST /restore:接收图片文件,返回修复后图像
5. 启动与测试服务
5.1 运行Flask应用
确保你在/root/GPEN目录下,并已放置gpen_service.py和app.py。
python app.py服务将在http://0.0.0.0:5000启动。
5.2 使用curl测试接口
准备一张测试图test.jpg,然后执行:
curl -X POST http://localhost:5000/restore \ -F "image=@./test.jpg" \ > restored.jpg如果一切正常,你会得到一张修复后的人像图片restored.jpg。
5.3 浏览器测试(可选)
你可以写一个简单的HTML页面上传图片,或者使用Postman等工具测试接口。
6. 部署优化建议
虽然我们实现了基本功能,但在真实场景中还需考虑以下几点:
6.1 性能优化
- GPU批处理:目前一次只处理一张图,可通过队列机制合并多个请求提升吞吐
- 缓存机制:对重复上传的图片做哈希去重,避免重复计算
- 异步处理:对于高延迟任务,可采用Celery+Redis实现异步处理,返回任务ID供轮询
6.2 安全性增强
- 文件类型校验:限制仅允许
.jpg,.png等常见图像格式 - 大小限制:设置最大上传尺寸(如10MB),防止恶意大文件攻击
- 防DDoS:结合Nginx限流,保护后端服务
6.3 日志与监控
添加日志记录请求时间、IP、处理耗时等信息,便于排查问题和性能分析。
import logging logging.basicConfig(level=logging.INFO)7. 常见问题与解决方案
7.1 模型路径找不到?
确保权重文件存在于:
/root/.cache/modelscope/hub/iic/cv_gpen_image-portrait-enhancement/weights/如果没有,请手动运行一次原始推理脚本触发自动下载:
python inference_gpen.py --input ./test.jpg7.2 CUDA out of memory?
GPEN在512×512分辨率下约占用4GB显存。若显存不足,可尝试:
- 使用CPU模式(修改
device = torch.device('cpu')) - 降低输入图像分辨率
- 启用混合精度(需修改模型代码)
7.3 多人脸处理不完整?
当前示例仅处理主脸。如需支持多人脸,请遍历self.face_helper.cropped_faces并逐个修复后合成。
8. 总结
8.1 你学到了什么?
本文带你完成了从GPEN模型本地推理到Web服务封装的全过程:
- 如何将命令行脚本改造成可复用的Python类
- 如何使用Flask暴露RESTful API接口
- 如何接收上传图片并返回处理结果
- 如何部署和测试一个完整的AI服务
你现在拥有的不再只是一个“能跑”的模型,而是一个可集成、可调用、可扩展的AI服务能力。
8.2 下一步可以做什么?
- 把这个服务打包成Docker镜像,方便迁移和部署
- 添加前端页面,做成在线人像修复网站
- 集成到微信小程序、App或其他业务系统中
- 结合FastAPI替换Flask,获得更好的性能和文档支持
只要你愿意,AI落地并没有想象中那么难。从一个简单的Flask接口开始,也许就是你通往AI工程化的第一步。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。