Download src/14_bundle.py from kaktusik21/3d-mesh-quality-control: direct link, hf CLI and curl.
- Browser
- Download file 5.51 kB
-
https://huggingface.co/kaktusik21/3d-mesh-quality-control/resolve/main/src/14_bundle.py
- Command line
-
hf download hf://kaktusik21/3d-mesh-quality-control/src/14_bundle.py
-
curl -L -o 14_bundle.py https://huggingface.co/kaktusik21/3d-mesh-quality-control/resolve/main/src/14_bundle.py
5.51 kB
| # KAGGLE: {"gpu": false, "internet": false, "kernels": ["alekstop/03-embed", "alekstop/07-finetune", "alekstop/08-stack2", "alekstop/11-release"]} | |
| # %% [markdown] | |
| # # 14 — Сборка релиза в одну папку | |
| # | |
| # Артефакты решения разбросаны по четырём ядрам, и каждое из них отдаёт вместе | |
| # с нужным файлом гигабайты ненужного (`03-embed` — 1.9 ГБ эмбеддингов ради | |
| # одного `emb_meta.json`). Ядро собирает только то, что требуется | |
| # `final_inference.ipynb`, в одну папку `release/`, которую остаётся скачать и | |
| # залить на HuggingFace. | |
| # | |
| # | что | откуда | зачем | | |
| # |---|---|---| | |
| # | `l1_*.joblib`, `l2_*.joblib`, `release_config.json` | `11-release` | ансамбль и пороги | | |
| # | `ft_fold{0..4}.pt`, `ft_meta.json` | `07-finetune` | дообученный DINOv3 | | |
| # | `pte_ft.npy`, `submission.csv` | `07`, `08` | сверка воспроизводимости | | |
| # | `emb_meta.json` | `03-embed` | какие бэкбоны и с каким разрешением считать | | |
| # %% | |
| import os, json, shutil, time | |
| from pathlib import Path | |
| T0 = time.time() | |
| WORK = Path(os.environ.get('MQC_WORK', '/kaggle/working')) | |
| IN = Path(os.environ.get('MQC_IN', '/kaggle/input')) | |
| REL = WORK / 'release' | |
| REL.mkdir(exist_ok=True) | |
| find = lambda pat: next(p for p in IN.rglob(pat)) | |
| # %% | |
| # --- копирование --- | |
| src_rel = find('release_config.json').parent | |
| n = 0 | |
| for p in sorted(src_rel.glob('*')): | |
| if p.is_file(): | |
| shutil.copy2(p, REL / p.name) | |
| n += 1 | |
| print('из 11-release:', n, 'файлов') | |
| FT_DIR = find('ft_meta.json').parent | |
| for name in ['ft_meta.json', 'pte_ft.npy', 'oof_ft.npy']: | |
| shutil.copy2(FT_DIR / name, REL / name) | |
| for p in sorted(FT_DIR.glob('ft_fold*.pt')): | |
| shutil.copy2(p, REL / p.name) | |
| print('из 07-finetune:', len(list(REL.glob('ft_fold*.pt'))), 'весов') | |
| shutil.copy2(find('emb_meta.json'), REL / 'emb_meta.json') | |
| # submission из 08 — эталон для сверки в Colab | |
| shutil.copy2(find('final_config.json').parent / 'submission.csv', REL / 'submission.csv') | |
| # %% | |
| # --- карточка репозитория --- | |
| CFG = json.load(open(REL / 'release_config.json')) | |
| EM = json.load(open(REL / 'emb_meta.json')) | |
| FTM = json.load(open(REL / 'ft_meta.json')) | |
| README = """--- | |
| license: mit | |
| tags: | |
| - 3d | |
| - mesh-quality | |
| - multi-label-classification | |
| --- | |
| # 3D Mesh Quality Control — артефакты решения | |
| Предсказание 10 дефектов 3D-меша и метки пригодности `quality` по мешу и шести | |
| рендерам карт нормалей. OOF-метрика соревнования: **f1_final = %.3f из 20** | |
| (quality %.4f, artefacts %.4f). | |
| ## Состав ансамбля | |
| | уровень | модель | OOF | | |
| |---|---|---| | |
| | 1 | дообученный %s @%d, multi-view | 14.236 | | |
| | 1 | LightGBM (эмбеддинги 4 бэкбонов + 472 признака) | 13.826 | | |
| | 1 | LightGBM (только признаки) | 13.048 | | |
| | 1 | логрег по эмбеддингам | 12.692 | | |
| | 2 | LightGBM по %d мета-признакам | 14.469 | | |
| | бленд | %.2f · уровень 2 + %.2f · дообученный ViT | **%.3f** | | |
| Замороженные бэкбоны: %s. | |
| ## Файлы | |
| * `lib_features.py`, `lib_embed.py`, `lib_model.py` — препроцессинг и модель, | |
| **сгенерированы из обучающих ядер**, а не написаны заново; | |
| * `l1_*.joblib`, `l2_*.joblib` — модели обоих уровней, по 5 фолдов; | |
| * `ft_fold{0..4}.pt` — веса дообученного ViT (fp16); | |
| * `release_config.json` — пороги пер-лейбл, состав ансамбля, порядок колонок; | |
| * `submission.csv`, `pte_ft.npy` — эталоны для сверки воспроизводимости. | |
| ## Использование | |
| Ноутбук `final_inference.ipynb` скачивает этот репозиторий целиком | |
| (`snapshot_download`, токен не нужен), считает признаки и выдаёт | |
| `submission.csv`, сверяя его с приложенным эталоном. | |
| """ % (CFG['oof_final'], CFG.get('oof_quality', 0.7442), CFG.get('oof_artefacts', 0.7114), | |
| FTM['backbone'], FTM['img'], 4 * 11 + 4, 1 - CFG['blend_w'], CFG['blend_w'], | |
| CFG['oof_final'], ', '.join(CFG['emb_order'])) | |
| (REL / 'README.md').write_text(README, encoding='utf-8') | |
| # %% | |
| # --- проверка комплектности --- | |
| need = (['release_config.json', 'emb_meta.json', 'ft_meta.json', 'pte_ft.npy', | |
| 'submission.csv', 'README.md'] | |
| + ['ft_fold%d.pt' % k for k in range(CFG['nfold'])] | |
| + ['l2_f%d_%s.joblib' % (k, t) for k in range(CFG['nfold']) | |
| for t in CFG['targets'] if t != 'intersection']) | |
| miss = [f for f in need if not (REL / f).exists()] | |
| print('НЕ ХВАТАЕТ:' if miss else 'комплект полный', miss[:10]) | |
| files = sorted(REL.glob('*')) | |
| size = sum(p.stat().st_size for p in files) | |
| print('релиз: %d файлов, %.1f МБ' % (len(files), size / 1e6)) | |
| for p in files: | |
| if p.stat().st_size > 5e6: | |
| print(' %-28s %7.1f МБ' % (p.name, p.stat().st_size / 1e6)) | |
| print('всего: %.1f мин' % ((time.time() - T0) / 60)) | |