supli6669 commited on
Commit ·
c4cb165
1
Parent(s): f8dfe41
fix(kaggle): resolve CUDA OOM, KeyError tensor(32) in ONNX export, and checkpoint export path
Browse files
models/CodeFormer/basicsr/archs/codeformer_arch.py
CHANGED
|
@@ -227,7 +227,7 @@ class CodeFormer(VQAutoEncoder):
|
|
| 227 |
for i, block in enumerate(self.encoder.blocks):
|
| 228 |
x = block(x)
|
| 229 |
if i in out_list:
|
| 230 |
-
enc_feat_dict[str(x.shape[-1])] = x.clone()
|
| 231 |
|
| 232 |
lq_feat = x
|
| 233 |
# ################# Transformer ###################
|
|
@@ -272,7 +272,7 @@ class CodeFormer(VQAutoEncoder):
|
|
| 272 |
for i, block in enumerate(self.generator.blocks):
|
| 273 |
x = block(x)
|
| 274 |
if i in fuse_list: # fuse after i-th block
|
| 275 |
-
f_size = str(x.shape[-1])
|
| 276 |
# Always execute to avoid data-dependent control flow in ONNX
|
| 277 |
x = self.fuse_convs_dict[f_size](enc_feat_dict[f_size].detach(), x, w)
|
| 278 |
out = x
|
|
|
|
| 227 |
for i, block in enumerate(self.encoder.blocks):
|
| 228 |
x = block(x)
|
| 229 |
if i in out_list:
|
| 230 |
+
enc_feat_dict[str(int(x.shape[-1]))] = x.clone()
|
| 231 |
|
| 232 |
lq_feat = x
|
| 233 |
# ################# Transformer ###################
|
|
|
|
| 272 |
for i, block in enumerate(self.generator.blocks):
|
| 273 |
x = block(x)
|
| 274 |
if i in fuse_list: # fuse after i-th block
|
| 275 |
+
f_size = str(int(x.shape[-1]))
|
| 276 |
# Always execute to avoid data-dependent control flow in ONNX
|
| 277 |
x = self.fuse_convs_dict[f_size](enc_feat_dict[f_size].detach(), x, w)
|
| 278 |
out = x
|
models/CodeFormer/options/CodeFormer_stage3_custom.yml
CHANGED
|
@@ -56,8 +56,8 @@ datasets:
|
|
| 56 |
- 5
|
| 57 |
- 50
|
| 58 |
latent_gt_path: null
|
| 59 |
-
num_worker_per_gpu:
|
| 60 |
-
batch_size_per_gpu:
|
| 61 |
dataset_enlarge_ratio: 5
|
| 62 |
prefetch_mode: cuda
|
| 63 |
pin_memory: true
|
|
|
|
| 56 |
- 5
|
| 57 |
- 50
|
| 58 |
latent_gt_path: null
|
| 59 |
+
num_worker_per_gpu: 2
|
| 60 |
+
batch_size_per_gpu: 2
|
| 61 |
dataset_enlarge_ratio: 5
|
| 62 |
prefetch_mode: cuda
|
| 63 |
pin_memory: true
|
train_custom.py
CHANGED
|
@@ -130,8 +130,9 @@ def main():
|
|
| 130 |
# workers which cause MemoryError/segfaults on Windows (Task 8).
|
| 131 |
dataset["prefetch_mode"] = None
|
| 132 |
else:
|
| 133 |
-
dataset["num_worker_per_gpu"] =
|
| 134 |
-
dataset["batch_size_per_gpu"] =
|
|
|
|
| 135 |
|
| 136 |
# Update weights path if they are in the project weights folder
|
| 137 |
project_weights_path = os.path.join(project_dir, "weights", "CodeFormer", "codeformer.pth")
|
|
@@ -212,6 +213,7 @@ def main():
|
|
| 212 |
else:
|
| 213 |
env["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
|
| 214 |
env["CUDA_VISIBLE_DEVICES"] = "0"
|
|
|
|
| 215 |
env["PYTHONPATH"] = os.path.pathsep.join([codeformer_dir, env.get("PYTHONPATH", "")])
|
| 216 |
|
| 217 |
print("\nStarting training process. Command:")
|
|
|
|
| 130 |
# workers which cause MemoryError/segfaults on Windows (Task 8).
|
| 131 |
dataset["prefetch_mode"] = None
|
| 132 |
else:
|
| 133 |
+
dataset["num_worker_per_gpu"] = 2
|
| 134 |
+
dataset["batch_size_per_gpu"] = 2
|
| 135 |
+
dataset["prefetch_mode"] = "cuda"
|
| 136 |
|
| 137 |
# Update weights path if they are in the project weights folder
|
| 138 |
project_weights_path = os.path.join(project_dir, "weights", "CodeFormer", "codeformer.pth")
|
|
|
|
| 213 |
else:
|
| 214 |
env["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
|
| 215 |
env["CUDA_VISIBLE_DEVICES"] = "0"
|
| 216 |
+
env["PYTORCH_CUDA_ALLOC_CONF"] = "expandable_segments:True"
|
| 217 |
env["PYTHONPATH"] = os.path.pathsep.join([codeformer_dir, env.get("PYTHONPATH", "")])
|
| 218 |
|
| 219 |
print("\nStarting training process. Command:")
|
train_kaggle.ipynb
CHANGED
|
@@ -4,7 +4,7 @@
|
|
| 4 |
"cell_type": "markdown",
|
| 5 |
"metadata": {},
|
| 6 |
"source": [
|
| 7 |
-
"#
|
| 8 |
"- Model: CodeFormer Stage III CFT Fine-Tuning with ArcFace Identity Loss\n",
|
| 9 |
"- Hardware: Kaggle Nvidia T4 / P100 GPU\n",
|
| 10 |
"- Target: 2,000 Iterations + ONNX Export"
|
|
@@ -48,7 +48,7 @@
|
|
| 48 |
"!git clone https://github.com/supli6669/Enhance-Image.git custom-ai-enhancer\n",
|
| 49 |
"%cd /kaggle/working/custom-ai-enhancer\n",
|
| 50 |
"\n",
|
| 51 |
-
"# 2. Install dependencies
|
| 52 |
"# this PyTorch (the latest onnxscript dropped ParamSchema which torch.onnx needs)\n",
|
| 53 |
"!pip install -q facexlib lpips gdown onnx 'onnxscript==0.1.0.dev20231023' onnxruntime-gpu pyyaml opencv-python scikit-image\n",
|
| 54 |
"!python tools/patch_and_install_basicsr.py\n",
|
|
@@ -67,7 +67,9 @@
|
|
| 67 |
"source": [
|
| 68 |
"# 4. Launch GPU Training with ArcFace Identity Loss\n",
|
| 69 |
"%cd /kaggle/working/custom-ai-enhancer\n",
|
| 70 |
-
"
|
|
|
|
|
|
|
| 71 |
]
|
| 72 |
},
|
| 73 |
{
|
|
@@ -77,54 +79,48 @@
|
|
| 77 |
"outputs": [],
|
| 78 |
"source": [
|
| 79 |
"# 5. Export to ONNX & INT8 Quantization\n",
|
| 80 |
-
"# Wrapped in try/except — ONNX export may fail on some PyTorch/onnxscript\n",
|
| 81 |
-
"# version combos but the .pth checkpoint is always saved regardless.\n",
|
| 82 |
"%cd /kaggle/working/custom-ai-enhancer\n",
|
|
|
|
| 83 |
"\n",
|
| 84 |
"onnx_ok = False\n",
|
| 85 |
"try:\n",
|
| 86 |
-
" ret = os.system(
|
| 87 |
-
" onnx_ok = (ret == 0) and os.path.exists(
|
| 88 |
" if onnx_ok:\n",
|
| 89 |
-
" print(
|
| 90 |
" else:\n",
|
| 91 |
-
" print(
|
| 92 |
"except Exception as e:\n",
|
| 93 |
-
" print(f
|
| 94 |
"\n",
|
| 95 |
"if onnx_ok:\n",
|
| 96 |
" try:\n",
|
| 97 |
-
" os.system(
|
| 98 |
" except Exception as e:\n",
|
| 99 |
-
" print(f
|
| 100 |
"\n",
|
| 101 |
-
"#
|
| 102 |
-
"
|
| 103 |
-
"
|
| 104 |
-
"
|
| 105 |
-
"}\n",
|
| 106 |
-
"for src, dst in copy_map.items():\n",
|
| 107 |
-
" if os.path.exists(src):\n",
|
| 108 |
-
" shutil.copy(src, dst)\n",
|
| 109 |
-
" print(f'Copied {src} -> {dst}')\n",
|
| 110 |
"\n",
|
| 111 |
-
"#
|
| 112 |
-
"
|
| 113 |
-
"pth_files = sorted(glob.glob('experiments/**/net_g_*.pth', recursive=True))\n",
|
| 114 |
"if pth_files:\n",
|
| 115 |
" latest = pth_files[-1]\n",
|
| 116 |
-
" shutil.copy(latest,
|
| 117 |
-
" print(f
|
| 118 |
"else:\n",
|
| 119 |
-
" print(
|
| 120 |
"\n",
|
| 121 |
-
"print(
|
| 122 |
-
"print(
|
| 123 |
-
"for f in os.listdir(
|
| 124 |
-
" fp = f
|
| 125 |
" if os.path.isfile(fp):\n",
|
| 126 |
" size_mb = os.path.getsize(fp) / 1024 / 1024\n",
|
| 127 |
-
" print(f
|
| 128 |
]
|
| 129 |
}
|
| 130 |
],
|
|
|
|
| 4 |
"cell_type": "markdown",
|
| 5 |
"metadata": {},
|
| 6 |
"source": [
|
| 7 |
+
"# \ud83d\ude80 Custom AI Enhancer \u2014 Kaggle Cloud GPU Training Pipeline\n",
|
| 8 |
"- Model: CodeFormer Stage III CFT Fine-Tuning with ArcFace Identity Loss\n",
|
| 9 |
"- Hardware: Kaggle Nvidia T4 / P100 GPU\n",
|
| 10 |
"- Target: 2,000 Iterations + ONNX Export"
|
|
|
|
| 48 |
"!git clone https://github.com/supli6669/Enhance-Image.git custom-ai-enhancer\n",
|
| 49 |
"%cd /kaggle/working/custom-ai-enhancer\n",
|
| 50 |
"\n",
|
| 51 |
+
"# 2. Install dependencies \u2014 pin onnxscript to a version compatible with\n",
|
| 52 |
"# this PyTorch (the latest onnxscript dropped ParamSchema which torch.onnx needs)\n",
|
| 53 |
"!pip install -q facexlib lpips gdown onnx 'onnxscript==0.1.0.dev20231023' onnxruntime-gpu pyyaml opencv-python scikit-image\n",
|
| 54 |
"!python tools/patch_and_install_basicsr.py\n",
|
|
|
|
| 67 |
"source": [
|
| 68 |
"# 4. Launch GPU Training with ArcFace Identity Loss\n",
|
| 69 |
"%cd /kaggle/working/custom-ai-enhancer\n",
|
| 70 |
+
"import os\n",
|
| 71 |
+
"os.environ[\"PYTORCH_CUDA_ALLOC_CONF\"] = \"expandable_segments:True\"\n",
|
| 72 |
+
"!python train_custom.py\n"
|
| 73 |
]
|
| 74 |
},
|
| 75 |
{
|
|
|
|
| 79 |
"outputs": [],
|
| 80 |
"source": [
|
| 81 |
"# 5. Export to ONNX & INT8 Quantization\n",
|
|
|
|
|
|
|
| 82 |
"%cd /kaggle/working/custom-ai-enhancer\n",
|
| 83 |
+
"import os, sys, shutil, glob\n",
|
| 84 |
"\n",
|
| 85 |
"onnx_ok = False\n",
|
| 86 |
"try:\n",
|
| 87 |
+
" ret = os.system(\"python tools/export_onnx.py\")\n",
|
| 88 |
+
" onnx_ok = (ret == 0) and os.path.exists(\"weights/CodeFormer/codeformer.onnx\")\n",
|
| 89 |
" if onnx_ok:\n",
|
| 90 |
+
" print(\"[OK] ONNX export succeeded.\")\n",
|
| 91 |
" else:\n",
|
| 92 |
+
" print(\"[WARN] ONNX export exited non-zero. Skipping quantization.\")\n",
|
| 93 |
"except Exception as e:\n",
|
| 94 |
+
" print(f\"[WARN] ONNX export failed: {e}. Skipping quantization.\")\n",
|
| 95 |
"\n",
|
| 96 |
"if onnx_ok:\n",
|
| 97 |
" try:\n",
|
| 98 |
+
" os.system(\"python tools/quantize_onnx_static.py\")\n",
|
| 99 |
" except Exception as e:\n",
|
| 100 |
+
" print(f\"[WARN] Quantization failed: {e}\")\n",
|
| 101 |
"\n",
|
| 102 |
+
"# Copy all ONNX and weight files to /kaggle/working/ for direct download\n",
|
| 103 |
+
"for f in glob.glob(\"weights/CodeFormer/codeformer*.*\"):\n",
|
| 104 |
+
" dst = os.path.join(\"/kaggle/working\", os.path.basename(f))\n",
|
| 105 |
+
" shutil.copy(f, dst)\n",
|
| 106 |
+
" print(f\"Copied {f} -> {dst}\")\n",
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
"\n",
|
| 108 |
+
"# Copy the best .pth checkpoint from models/CodeFormer/experiments\n",
|
| 109 |
+
"pth_files = sorted(glob.glob(\"models/CodeFormer/experiments/**/net_g_*.pth\", recursive=True) + glob.glob(\"experiments/**/net_g_*.pth\", recursive=True))\n",
|
|
|
|
| 110 |
"if pth_files:\n",
|
| 111 |
" latest = pth_files[-1]\n",
|
| 112 |
+
" shutil.copy(latest, \"/kaggle/working/codeformer_finetuned_v3.pth\")\n",
|
| 113 |
+
" print(f\"Checkpoint saved: {latest} -> /kaggle/working/codeformer_finetuned_v3.pth\")\n",
|
| 114 |
"else:\n",
|
| 115 |
+
" print(\"[WARN] No .pth checkpoint found in experiments/\")\n",
|
| 116 |
"\n",
|
| 117 |
+
"print(\"\\nTraining and Export finished! Outputs saved in /kaggle/working/\")\n",
|
| 118 |
+
"print(\"Files available for download:\")\n",
|
| 119 |
+
"for f in os.listdir(\"/kaggle/working\"):\n",
|
| 120 |
+
" fp = f\"/kaggle/working/{f}\"\n",
|
| 121 |
" if os.path.isfile(fp):\n",
|
| 122 |
" size_mb = os.path.getsize(fp) / 1024 / 1024\n",
|
| 123 |
+
" print(f\" {f}: {size_mb:.1f} MB\")\n"
|
| 124 |
]
|
| 125 |
}
|
| 126 |
],
|