Implement AI Host functionality with model caching and job management
- Added ai_host.py to handle AI tasks with FastAPI integration. - Introduced HostState and ModelCache classes for managing client connections and model loading. - Implemented job submission and cancellation endpoints in the AI host. - Enhanced tests for AI host functionality, including client tracking and job cancellation. - Updated existing tests to accommodate changes in the operator and command structure. - Refactored runtime commands to use request-based architecture instead of command-line arguments. - Improved model loading logic to handle CUDA memory management and reuse models efficiently.
This commit is contained in:
66
README.md
66
README.md
@@ -9,15 +9,18 @@
|
||||
## 当前功能
|
||||
|
||||
- 使用 Blender Extension manifest,可通过 `Install from Disk` 安装
|
||||
- 在独立 Python Runtime 中运行 Torch 与 DA3,避免污染 Blender Python 进程
|
||||
- 在独立 Python Runtime 的常驻 HTTP AI Host 中运行 Torch、DA3 与 BEN2,避免污染 Blender Python 进程
|
||||
- Blender 使用内置 `urllib.request` 访问仅监听 `127.0.0.1` 的 Host;请求带随机 Token
|
||||
- 常驻 Host 复用 Torch、CUDA、BEN2 与最近使用的 DA3 模型,连续执行时不再重复加载
|
||||
- 多个 Blender 实例自动连接同一个共享 Host;`Host` 面板显示状态、端口、客户端与模型缓存,并提供安装、启动、清理、重启和停止控制
|
||||
- Runtime、模型和任务结果默认保存在 `~/.snapform`,可由多个 Blender 版本共享
|
||||
- 支持 DA3 Small、Base、Large 1.1、Giant 1.1 和 Nested Giant Large 1.1
|
||||
- 支持 BEN2 Base 单图背景剔除测试,输出透明 PNG 与推理耗时
|
||||
- 支持单张 JPG、JPEG、PNG、WEBP 图片或常见视频文件输入
|
||||
- 视频均匀抽帧,可设置参与重建的最大帧数
|
||||
- `Setup` 集中管理 Runtime,并逐项列出和下载所有可用模型
|
||||
- `Host > Models` 默认折叠,展开后可逐项查看和下载所有可用模型
|
||||
- Runtime 已就绪时不额外占用面板空间;模型列表每个模型只占一行
|
||||
- `Debug` 是独立且默认折叠的 AI 功能测试面板
|
||||
- `Debug` 默认折叠,内部的 DA3 与 BEN2 测试项也分别默认折叠
|
||||
- 使用一个导出类型下拉菜单和一个 `Export` 按钮
|
||||
- 只显示当前格式的专属参数;GLB 与 PLY 设置不会同时出现
|
||||
- Debug 的模型选项按格式过滤;PLY 只提供两个带 Gaussian head 的 Giant 模型
|
||||
@@ -31,7 +34,7 @@
|
||||
- 转换对话框可选择推理模式、处理分辨率和面片网格细分
|
||||
- Debug 的 DA3 导出或 BEN2 背景剔除完成后只打开对应 job 文件夹,不向当前 Blender 文件添加任何数据
|
||||
- 完整保留每次任务生成的所有官方文件
|
||||
- 安装、模型下载和推理均在后台子进程运行,状态栏实时显示阶段、百分比进度条与取消按钮
|
||||
- 安装和模型下载使用后台子进程;推理提交给常驻 AI Host,状态栏实时显示阶段、百分比进度条与取消按钮
|
||||
- 后台任务运行时,Install、Download 和 Export 按钮保持原位置并变灰,任务完成后恢复
|
||||
|
||||
## 使用
|
||||
@@ -39,19 +42,20 @@
|
||||
1. 使用 `uv run python pack.py` 构建 Extension ZIP。
|
||||
2. 在 Blender 的 `Preferences > Extensions` 中选择 `Install from Disk`。
|
||||
3. 在 Extension Preferences 中确认 `uv` 路径和 Torch Backend。
|
||||
4. 点击 `Install Runtime`。首次安装会下载 Python、PyTorch、DA3 和 BEN2 依赖。
|
||||
4. 在 `Host` 点击 `Install Runtime`。首次安装会下载 Python、PyTorch、DA3、BEN2、FastAPI、Uvicorn,
|
||||
并默认下载 `DA3 Small`、`DA3 Base` 和 `BEN2 Base` 模型。
|
||||
5. 在 3D View 按 `N`,打开 `SnapForm` 页签。
|
||||
6. 在 `Setup` 中找到需要的模型并点击该行的 `Download`。
|
||||
6. 如需其他模型,展开 `Host > Models`,找到模型并点击该行的 `Download`。
|
||||
7. 展开默认收起的 `Debug`,选择 `Export Format` 和本次执行使用的模型。
|
||||
8. 选择一张图片或一个视频文件。视频可设置均匀抽取的帧数,然后点击 `Export`。
|
||||
9. 测试背景剔除时,在 `Setup` 下载 `BEN2 Base`,然后在 `Debug` 的
|
||||
9. 测试背景剔除时,确认 `Host > Models` 中的 `BEN2 Base` 已就绪,然后在 `Debug` 的
|
||||
`BEN2 Background Removal` 区域选择单张图片并点击 `Remove Background`。
|
||||
完成后会打开 job 文件夹,其中的 `foreground.png` 带透明 Alpha;状态栏显示
|
||||
BEN2 推理、模型加载与任务总耗时。当前测试固定关闭较慢的 foreground refinement。
|
||||
|
||||
## Image Empty 去背景
|
||||
|
||||
1. 在 `Setup` 下载 `BEN2 Base`。
|
||||
1. 确认 `Host > Models` 中的 `BEN2 Base` 已就绪;首次安装 Runtime 时会默认下载。
|
||||
2. 在 3D View 选中 Image Empty,右键选择 `Remove Background`。
|
||||
3. 完成后以 Fake User 保留原 Image datablock,新建并 Pack 一张透明 PNG 到当前 `.blend`,然后只把
|
||||
当前 Empty 的 `data` 换成新图;Empty 的 Transform、显示尺寸、Offset 及其他设置保持不变。
|
||||
@@ -66,16 +70,17 @@
|
||||
1. 在 3D View 选中 `Object Type = Empty`、`Display As = Image` 的对象。
|
||||
2. 右键选择 `Convert to Depth Plane`,通过 `Depth from` 选择深度来源:
|
||||
- `AI Generated`:显示 Model、Use Ray Pose 和 Resolution Scale。实际 Process Res 为图片长边像素数
|
||||
乘以 Resolution Scale;范围为 `0.1–1.0`,默认 `0.5`。计算后的 Process Res 会直接显示在
|
||||
乘以 Resolution Scale;范围为 `0.1–1.0`,默认 `1.0`。计算后的 Process Res 会直接显示在
|
||||
`Resolution Scale (… px)` 标签中。
|
||||
转换导出 `mini_npz`,使用前需要在
|
||||
`Setup` 下载所选模型,并固定使用 `process_res_method="upper_bound_resize"`;设备和参考视图策略
|
||||
继续使用场景设置。
|
||||
`Host > Models` 下载所选模型,并固定使用 `process_res_method="upper_bound_resize"`;设备和参考视图策略
|
||||
继续使用场景设置。Model 下拉菜单只列出已经下载的 DA3 模型;若没有可用模型,对话框会引导到
|
||||
`Host > Models` 下载。
|
||||
- `Original`:直接把原图作为深度贴图,不显示估算参数。Remove Background 关闭时不启动
|
||||
Runtime,也不要求源图片存在于磁盘。
|
||||
`Original` 是默认深度来源。选择 `AI Generated` 时,其 Model、Use Ray Pose 与 Resolution Scale
|
||||
参数会集中显示在独立边框中。两种模式始终显示 Remove Background、Displace via、Unshaded、
|
||||
Subdivision 与 Delete Original。
|
||||
参数会集中显示在独立边框中。两种模式都有默认折叠的 Options,内部依次为 Displace via、
|
||||
Subdivision、Remove Background 和 Unshaded;Delete Original 保持在折叠项外。
|
||||
Remove Background 默认关闭,与 Depth from 无关;开启后需要下载 `BEN2 Base`,并从原图生成、
|
||||
Pack `.rb` 透明图片。它只替换生成面片材质的颜色图片,不修改源 Image Empty 的 Image datablock。
|
||||
AI Generated 仍从原图生成 `.depth`;例如 `img.png` 会得到 `img.rb` 与 `img.depth`,不会生成
|
||||
@@ -130,8 +135,9 @@ Principled BSDF 的 `Base Color`,并通过
|
||||
`0.001`,会乘以面片 Transform 的统一缩放倍率。原图 Color 还会经过 `Float Curve` 连接到
|
||||
Principled BSDF 的 `Roughness`,曲线两端输出分别为 `0.5` 和 `0.1`;材质 IOR 保持
|
||||
Principled BSDF 默认值 `1.5`。
|
||||
开启 `Unshaded` 后,Surface 改为原图 Color 直接连接 Emission,再连接 Material Output;不创建
|
||||
Principled BSDF、Bump 或 Float Curve。若 Displace via 选择 `Material`,深度贴图与 Displacement
|
||||
开启 `Unshaded` 后,原图 Color 连接 Emission,原图 Alpha 作为 Mix Shader 系数,在
|
||||
Transparent BSDF 与 Emission 之间混合后连接 Material Output;不创建 Principled BSDF、Bump 或
|
||||
Float Curve。若 Displace via 选择 `Material`,深度贴图与 Displacement
|
||||
节点仍会保留并连接 Material Output 的 Displacement。
|
||||
|
||||
这里的“原始距离”是 DA3 模型输出的尺度。普通 Small、Base、Large 和 Giant 模型的深度不应
|
||||
@@ -219,6 +225,7 @@ Extension 本身不包含 Torch。`Install Runtime` 使用 `uv` 创建独立 Pyt
|
||||
- xFormers 0.0.33.post2(与 PyTorch 2.9.1 对应)
|
||||
- 固定到已验证 commit 的 Depth Anything 3
|
||||
- 固定到已验证 commit 的 BEN2
|
||||
- FastAPI 0.139.2 与 Uvicorn 0.51.0
|
||||
- 固定到 DA3 官方推荐 commit 的 `gsplat`;仅安装 PLY 导出所需的纯 Python 部分,
|
||||
不编译本机 CUDA rasterizer
|
||||
- `addict` 2.4.0(补充 DA3 上游包元数据暂未声明的运行依赖)
|
||||
@@ -226,19 +233,43 @@ Extension 本身不包含 Torch。`Install Runtime` 使用 `uv` 创建独立 Pyt
|
||||
默认 CUDA Backend 为 CUDA 12.8,也可以选择 CPU。CPU 可以用于验证,但实际推理
|
||||
通常很慢。
|
||||
|
||||
Extension 启用后只会查找已有的共享 AI Host,不会主动启动新进程。第一次执行 AI 操作或在侧边栏
|
||||
手动点击 `Start` 时才会启动 Host。Host 只绑定回环地址,并让操作系统分配动态端口;第一个实例把
|
||||
端口、进程和随机 Token 写入 `host.json`,其余 Blender 通过标准库
|
||||
`urllib.request` 连接同一个 Host。`host.lock` 保证同一 Storage Root 同时只有一个 Host,Token
|
||||
则阻止同机其他进程直接调用接口。Host 全局同时只执行一个 AI 任务。
|
||||
|
||||
每个 Blender 会注册独立客户端并每 5 秒发送心跳。正常关闭 Blender 时仅注销自身,不会直接终止
|
||||
其他 Blender 正在使用的 Host;异常退出的客户端会在 20 秒后过期。最后一个客户端离开后,Host
|
||||
保留模型缓存等待 60 秒,再在空闲时自动退出。取消任务不会重启 Host,并会保留已经加载的模型;
|
||||
如果取消发生在一次不可中断的 Torch 调用中,任务会在该调用返回后的最近检查点结束。
|
||||
|
||||
侧边栏 `Host` 面板以 `Running (Clients: n)` 表示空闲服务,以 `Running (Busy)` 表示正在执行任务,
|
||||
并显示缓存模型和活动任务。空闲且只有当前 Blender 连接时,可以清理模型缓存、重启或停止 Host;
|
||||
多客户端或任务执行期间不会允许破坏共享服务。
|
||||
|
||||
BEN2 在首次使用后保持加载;DA3 保留最近使用的一个模型。切换 DA3 模型时会释放旧模型;加载时如果
|
||||
显存不足,会先释放另一类缓存模型并重试。
|
||||
|
||||
Runtime Schema 已升级,旧 Runtime 需要重新执行 `Install Runtime` 才能安装 HTTP Host 依赖。
|
||||
Host 的启动和崩溃日志写入 `~/.snapform/ai-host.log`。
|
||||
|
||||
Runtime、模型和任务结果默认保存在用户主目录的 `~/.snapform`:
|
||||
|
||||
```text
|
||||
~/.snapform/
|
||||
├── runtime/
|
||||
├── models/
|
||||
└── jobs/
|
||||
├── jobs/
|
||||
├── ai-host.log
|
||||
├── host.json # Host 运行时存在
|
||||
└── host.lock # Host 运行时持有
|
||||
```
|
||||
|
||||
不同 Blender 版本安装相同 Extension 后会共用这个目录。也可以在 Extension
|
||||
Preferences 的 `Storage Root` 中修改共享位置。不要把模型写入 Extension 安装目录,
|
||||
因为该目录可能只读,并且升级时会被替换。不要同时从多个 Blender 实例执行
|
||||
`Install Runtime`;推理任务和模型读取可以共享。
|
||||
`Install Runtime`;推理 Host、任务队列和模型读取可以共享。
|
||||
|
||||
## 开发
|
||||
|
||||
@@ -255,6 +286,7 @@ uv run python pack.py
|
||||
├── src/
|
||||
│ └── snapform/
|
||||
│ ├── blender_manifest.toml
|
||||
│ ├── ai_host.py
|
||||
│ ├── bootstrap_runtime.py
|
||||
│ ├── models.py
|
||||
│ ├── image_depth.py
|
||||
|
||||
Reference in New Issue
Block a user