mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
fix: offline CodeFormer face-enhance (ship RealESRGAN_x2plus in upscale-enhance bundle) (#433)
* fix: ship RealESRGAN_x2plus.pth in the upscale-enhance bundle for offline CodeFormer codeformer-pip 0.0.4 downloads RealESRGAN_x2plus.pth at import of codeformer.app, unconditionally, even though enhance_faces calls inference_app with background_enhance=False and never uses the background upsampler. The weight was not bundled, so explicit CodeFormer face-enhance (enhance-faces model=codeformer) failed in strict offline mode (SNAPOTTER_ALLOW_MODEL_DOWNLOAD=0) on a host that had never cached it -- the guard raised before the import could complete. Add RealESRGAN_x2plus.pth to the upscale-enhance bundle manifest (only that bundle uses codeformer-pip; photo-restoration uses the CodeFormer ONNX path) and link it in prepare_codeformer_weights alongside the other three weights, replacing the download-or-error guard. Once the bundle ships it, the import resolves offline and strict mode works. Archive SHA256s updated in a follow-up once the bundle is rebuilt. Claude-Session: https://claude.ai/code/session_01XGB4pGvTvb7sUX4JN745U7 * fix: require face-detection bundle for enhance-faces + point manifest at the x2plus archives enhance-faces runs MediaPipe face detection (blaze_face_short_range.tflite) before CodeFormer/GFPGAN. That model ships in the face-detection bundle, not the tool's primary upscale-enhance bundle, so a standalone upscale-enhance install failed face detection (offline: hard error; online: a surprise download) before reaching the codeformer path. Declare the dependency in TOOL_EXTRA_BUNDLES like passport-photo does. Update the upscale-enhance archive SHA256/sizes to the rebuilt bundles that include RealESRGAN_x2plus.pth (amd64-gpu + arm64-cpu), verified to install and run enhance-faces model=codeformer in strict offline mode with zero downloads. Claude-Session: https://claude.ai/code/session_01XGB4pGvTvb7sUX4JN745U7
This commit is contained in:
@@ -194,15 +194,15 @@
|
||||
"archives": {
|
||||
"amd64-gpu": {
|
||||
"file": "v2.0.0/upscale-enhance-amd64-gpu.tar.gz",
|
||||
"sha256": "37f0e7a62dcb83b2dc0760532fb41ac9d1c40d336abe1aea01d889ad039ebc65",
|
||||
"compressedSize": 5314188723,
|
||||
"extractedSize": 8412712960
|
||||
"sha256": "089fdecbcd36090013ed4adf3a96650c757ce06871c2e1f1b155ccdd8487e413",
|
||||
"compressedSize": 5376987856,
|
||||
"extractedSize": 8455327174
|
||||
},
|
||||
"arm64-cpu": {
|
||||
"file": "v2.0.0/upscale-enhance-arm64-cpu.tar.gz",
|
||||
"sha256": "de65321f1cc5d5664c63e38e49cd39c36fe88e0569d666821e982ff6d6999bea",
|
||||
"compressedSize": 2262502457,
|
||||
"extractedSize": 0
|
||||
"sha256": "b9e948c8308371ccb3defce4323a85884e46d5bde52791115d34d1c1f92e4f23",
|
||||
"compressedSize": 2335658971,
|
||||
"extractedSize": 3661453942
|
||||
}
|
||||
},
|
||||
"packages": {
|
||||
@@ -234,6 +234,12 @@
|
||||
"path": "realesrgan/RealESRGAN_x4plus.pth",
|
||||
"minSize": 60000000
|
||||
},
|
||||
{
|
||||
"id": "realesrgan-x2plus",
|
||||
"url": "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.1/RealESRGAN_x2plus.pth",
|
||||
"path": "realesrgan/RealESRGAN_x2plus.pth",
|
||||
"minSize": 60000000
|
||||
},
|
||||
{
|
||||
"id": "gfpgan-v1.3",
|
||||
"url": "https://github.com/TencentARC/GFPGAN/releases/download/v1.3.0/GFPGANv1.3.pth",
|
||||
|
||||
@@ -82,11 +82,11 @@ def prepare_codeformer_weights(models_base):
|
||||
"""Resolve codeformer-pip's cwd-relative weights offline.
|
||||
|
||||
codeformer-pip 0.0.4 downloads four weights into a cwd-relative
|
||||
CodeFormer/weights/ tree at import time of codeformer.app. Three of them
|
||||
ship in the feature bundles and are linked here so they never re-download;
|
||||
RealESRGAN_x2plus.pth (a background-upscale helper this app never invokes)
|
||||
is not bundled, so it downloads once on first use unless strict offline
|
||||
mode blocks it.
|
||||
CodeFormer/weights/ tree at import time of codeformer.app -- unconditionally,
|
||||
even though this app calls inference_app with background_enhance=False and so
|
||||
never uses the RealESRGAN background upsampler (RealESRGAN_x2plus.pth). All
|
||||
four ship in the upscale-enhance bundle and are linked here from models_base
|
||||
so the import never triggers a download; strict offline mode then works.
|
||||
"""
|
||||
expected = {
|
||||
os.path.join("CodeFormer", "weights", "CodeFormer", "codeformer.pth"): os.path.join(
|
||||
@@ -98,11 +98,10 @@ def prepare_codeformer_weights(models_base):
|
||||
os.path.join("CodeFormer", "weights", "facelib", "parsing_parsenet.pth"): os.path.join(
|
||||
models_base, "gfpgan", "facelib", "parsing_parsenet.pth"
|
||||
),
|
||||
os.path.join("CodeFormer", "weights", "realesrgan", "RealESRGAN_x2plus.pth"): os.path.join(
|
||||
models_base, "realesrgan", "RealESRGAN_x2plus.pth"
|
||||
),
|
||||
}
|
||||
for link, target in expected.items():
|
||||
if not link_bundled_weight(link, target):
|
||||
ensure_download_allowed(f"CodeFormer weight {os.path.basename(link)}")
|
||||
|
||||
x2plus = os.path.join("CodeFormer", "weights", "realesrgan", "RealESRGAN_x2plus.pth")
|
||||
if not os.path.exists(x2plus):
|
||||
ensure_download_allowed("CodeFormer helper weight RealESRGAN_x2plus.pth")
|
||||
|
||||
@@ -112,6 +112,11 @@ export function getToolsForBundle(bundleId: string): string[] {
|
||||
*/
|
||||
export const TOOL_EXTRA_BUNDLES: Record<string, string[]> = {
|
||||
"passport-photo": ["face-detection"],
|
||||
// enhance-faces runs MediaPipe face detection (blaze_face) before CodeFormer/
|
||||
// GFPGAN; that model ships in face-detection, not its primary upscale-enhance
|
||||
// bundle, so require both or it fails on a standalone install (offline: hard
|
||||
// error; online: a surprise download).
|
||||
"enhance-faces": ["face-detection"],
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user