Android 学生项目有哪些可用的免费 virtual try-on API?
学生项目可以免费完成演示,但会受到配额和排队限制
建议先通过 gradio_client 调用 Hugging Face 上的虚拟试衣 Space,再用 FastAPI 为 Android 应用提供自己的 REST 接口。
这样不用训练模型,手机也不需要运行模型。公共 Space 的可用性取决于维护者和平台资源,无法保证每次都立即返回结果。Hugging Face 的 ZeroGPU Space 可以免费使用,但有配额和队列限制。ZeroGPU 官方说明
如果学校能提供 GPU,自己部署预训练模型更方便控制演示环境。模型代码和权重可以免费获取,计算资源仍需自行解决。
有哪些实际可用的选择?
| 方案 | 免费的前提 | 适合的情况 | 主要限制 |
|---|---|---|---|
| 调用现有 ZeroGPU Space | Space 开放访问,且剩余配额足够 | 先做出能运行的项目演示 | 排队、配额耗尽、上游接口变化 |
| 在自己的 ZeroGPU Space 部署 | 账号满足托管条件,应用兼容 ZeroGPU | 希望控制代码和参数 | 仍受共享 GPU 和配额限制 |
| 学校或个人 GPU 部署预训练模型 | 已有可使用的 GPU | 答辩时需要控制运行环境 | 需要配置依赖、下载权重和维护服务 |
使用现有 ZeroGPU Space 和自己托管 Space 的条件不同。能否免费托管,要看账号设置和官方要求。复制 Space 时也要检查硬件选项,普通 GPU 实例可能产生费用。Gradio 客户端说明
Hugging Face 上有模型仓库,也不代表该模型有免费的托管推理 API。Spaces、Inference Providers 和 Inference Endpoints 是不同的服务。当前 Inference Providers 定价页列出的免费账号月度赠送额度为 None,做项目预算时不能直接沿用过去介绍的免费额度。Inference Providers 定价
Hugging Face Space 能转成 API 吗?
如果 Space 使用 Gradio,并且开放了可调用的端点,通常就能通过 API 使用。打开应用底部的 Use via API 或 View API,可以查看平台生成的调用示例。通过 API 接入后,公共演示服务的排队和资源限制依然存在。
也可以安装 Python 客户端:
pip install gradio_client
以 IDM-VTON Space 为例,先检查接口:
import os
from gradio_client import Client
client = Client(
"yisol/IDM-VTON",
token=os.getenv("HF_TOKEN"),
)
client.view_api()
view_api() 会显示端点名称、输入参数和输出类型;文件输入通常通过 handle_file() 上传。Gradio Python 客户端指南
接入时需要注意:
- 按目标 Space 的 API 文档填写参数。人物图可能是
ImageEditor对象,需要background、layers等字段,不能只传一个图片路径。 - 优先使用
/tryon这样的命名端点。fn_index容易随界面修改而变化,尽量避免依赖它。 - 不要假定所有 Space 都有统一的
/predictHTTP 接口。上传、排队和获取结果可能涉及多个请求,交给客户端处理更省事。 - 如果 Space 没有开放端点,或不允许这种使用方式,就需要换一个 Space,或者在许可证允许的范围内部署自己的副本。
如何通过 FastAPI 接入 Android?
建议让 Android 只访问自己的后端:
Android (Java)
→ FastAPI:接收人物图和服装图
→ Gradio Space 或自己部署的模型
→ FastAPI:返回生成图片
→ Android:显示结果
这样可以把 Hugging Face token 留在服务器上,以后更换模型也方便。
下面的同步演示接口按 IDM-VTON Space 源码中的 /tryon 端点传入参数,启用自动生成 mask,并取第一个输出作为试衣结果。这里的自动 mask 针对上衣区域,适合先验证上衣试穿流程。IDM-VTON Space 源码
公共 Space 更新后,参数可能变化,运行前应重新执行 view_api() 核对。这段代码仅用于演示接入方式,公共服务能否随时使用尚未经过验证。
安装依赖:
pip install fastapi uvicorn python-multipart gradio_client pillow
app.py:
import os
from io import BytesIO
from pathlib import Path
from tempfile import TemporaryDirectory
from fastapi import FastAPI, File, Form, HTTPException
from fastapi.responses import Response
from gradio_client import Client, handle_file
from PIL import Image, ImageOps, UnidentifiedImageError
app = FastAPI()
MAX_BYTES = 5 * 1024 * 1024 # 示例自行设置的单图限制
def save_image(data: bytes, target: Path):
if not data or len(data) > MAX_BYTES:
raise HTTPException(400, "图片不能为空,且不得超过 5 MiB")
try:
with Image.open(BytesIO(data)) as image:
image = ImageOps.exif_transpose(image).convert("RGB")
image.save(target, format="PNG")
except (UnidentifiedImageError, OSError, ValueError) as exc:
raise HTTPException(400, "无法读取图片") from exc
@app.post("/try-on")
def try_on(
person: bytes = File(...),
garment: bytes = File(...),
description: str = Form("a shirt"),
):
with TemporaryDirectory() as directory:
root = Path(directory)
person_path = root / "person.png"
garment_path = root / "garment.png"
save_image(person, person_path)
save_image(garment, garment_path)
try:
client = Client(
"yisol/IDM-VTON",
token=os.getenv("HF_TOKEN"),
download_files=str(root / "outputs"),
)
result = client.predict(
dict={
"background": handle_file(str(person_path)),
"layers": [],
"composite": None,
},
garm_img=handle_file(str(garment_path)),
garment_des=description,
is_checked=True,
is_checked_crop=False,
denoise_steps=30,
seed=42,
api_name="/tryon",
)
output = BytesIO()
with Image.open(result[0]) as image:
image.convert("RGB").save(output, format="PNG")
except Exception as exc:
# 实际项目应在服务器记录错误,并细分配额、网络等问题。
raise HTTPException(502, "试衣服务暂时无法完成请求") from exc
return Response(output.getvalue(), media_type="image/png")
FastAPI 接收文件上传需要 python-multipart。文件和 description 会通过 multipart/form-data 一起提交。FastAPI 文件上传文档
启动:
uvicorn app:app --host 0.0.0.0 --port 8000
测试后端:
curl -X POST http://127.0.0.1:8000/try-on \
-F "person=@person.jpg" \
-F "garment=@shirt.jpg" \
-F "description=a blue shirt" \
--output result.png
Android 端可以用现有的 OkHttp 或 Retrofit,以相同字段名上传两张图片,再将成功响应作为图片读取。调用应放在后台线程,同时显示等待状态。
示例中的 token、download_files 和阻塞式 predict() 都来自当前客户端接口。如果使用旧版依赖,应核对对应版本的文档。Client 参数说明
自己部署时,优先考虑哪些模型?
CatVTON:有 GPU 时可以优先评估
CatVTON 官方仓库提供预训练权重和 Gradio 应用,无需从头训练。仓库说明,在指定的 bf16 配置下,生成 1024×768 图片约需 8 GB 显存。
这一显存需求有配置前提,并不保证任意 8 GB 显卡都能运行完整服务。部署时还要考虑预处理和并发请求的资源占用,以及 CUDA 依赖。
可以按以下顺序部署:
- 按仓库要求建立独立环境,先跑通官方 Gradio 应用。
- 用自己的图片确认 mask、服装类别和输出效果。
- 让 FastAPI 调用本地 Gradio 服务,或者提取推理函数供后端调用。
- 在单张 GPU 上先串行处理请求,验证后再考虑并发。
IDM-VTON:可复用演示流程,但预处理依赖较多
IDM-VTON 官方仓库提供预训练模型和本地 Gradio 演示。部署需要准备 human parsing、OpenPose、DensePose 等组件或检查点。接入用户上传的图片时,应沿用演示应用的预处理流程,避免直接把面向数据集的批量推理脚本当作上传接口。
这两个项目都声明采用 CC BY-NC-SA 4.0,有非商业使用等条件。学校项目也应按要求保留署名;后续若转成商业应用,需要重新检查授权及相关依赖的许可证。CatVTON 许可说明、IDM-VTON 许可说明
做课程演示时,需要处理哪些问题?
先把范围收窄到一种服装,例如上衣。人物照片尽量选择正面、身体区域完整且遮挡较少的,服装图则选择背景干净的,再逐步确认模型能处理哪些输入。生成图只能展示外观效果,不能用来判断实际尺码是否合适。
后端还需要补上以下处理:
- 排队时间较长时,提交任务后先返回
job_id,由 Android 查询状态,避免一直占用一个 HTTP 请求。 - 分别提示配额耗尽、网络失败和图片不合要求等问题,避免无限重试。
- 限制上传体积、图片像素和请求并发。示例中的字节检查发生在请求解析之后,部署时还应在入口处设置上传限制。
- 告知用户照片会发送给哪些服务,并清理自己服务中的临时文件。公共 Space 如何保留数据,需要单独确认。
没有 GPU 时,可以先用现有 Space 跑通端到端流程,再准备几组明确标注为预生成的演示结果,应对答辩现场的排队或网络故障。如果学校能提供 GPU,再迁移到自己部署的 CatVTON 或 IDM-VTON,保留 Android 到 FastAPI 的接口即可。
备注:内容仅供参考。
