Download stage_v2.py from Lucasgitguy-co/forma3d-tiny-2: direct link, hf CLI and curl.
- Browser
- Download file 7.95 kB
-
https://huggingface.co/Lucasgitguy-co/forma3d-tiny-2/resolve/main/stage_v2.py
- Command line
-
hf download hf://Lucasgitguy-co/forma3d-tiny-2/stage_v2.py
-
curl -L -o stage_v2.py https://huggingface.co/Lucasgitguy-co/forma3d-tiny-2/resolve/main/stage_v2.py
7.95 kB
| """Evaluate versus pinned forma3d-tiny, stage honest v2 metadata, never upload.""" | |
| import argparse | |
| import hashlib | |
| import importlib.util | |
| import json | |
| import shutil | |
| from pathlib import Path | |
| import torch | |
| from audit_data import audit | |
| ROOT = Path(__file__).resolve().parent | |
| REV = 'e80b8d895cc2e405894473abe4ce40b3472eaca7' | |
| BASE = 'Lucasgitguy-co/forma3d-tiny' | |
| def sha(p): | |
| return hashlib.sha256(Path(p).read_bytes()).hexdigest() | |
| def main(): | |
| p = argparse.ArgumentParser() | |
| for name in ('run','data','base','release'): | |
| p.add_argument('--'+name, required=True) | |
| p.add_argument('--device', default='mps', choices=['mps','cpu']) | |
| args = p.parse_args() | |
| destination = Path(args.release) | |
| if destination.exists(): | |
| raise ValueError('Release directory exists; choose a fresh --release path') | |
| audit(args.data, ROOT / 'upstream/ATTRIBUTIONS.json') | |
| # Ensure the asserted parent is the pinned public checkpoint, not another run. | |
| if sha(args.base) != '83c065d2a50cf086928542cf8d40dc4416b379e38b9aa61d842dc9106d4b3306': | |
| raise ValueError('Expected the pinned published forma3d-tiny model.pt') | |
| spec = importlib.util.spec_from_file_location('pinned_release', ROOT / 'upstream/scripts/release.py') | |
| module = importlib.util.module_from_spec(spec) | |
| spec.loader.exec_module(module) | |
| checkpoint, meta, report = module.evaluate_release(args) | |
| # Upstream gate checks completed training, validation loss, held-out loss/IoU, | |
| # source separation, initialization hash and nonempty qualitative predictions. | |
| source = ROOT / 'upstream' | |
| destination.mkdir(parents=True) | |
| for folder in ('src','licenses'): | |
| shutil.copytree(source / folder, destination / folder, | |
| ignore=shutil.ignore_patterns('__pycache__','*.egg-info')) | |
| for name in ('LICENSE','NOTICE','THIRD_PARTY.md','DATASETS.md','requirements-tested-macos.txt'): | |
| shutil.copyfile(source / name, destination / name) | |
| project = (source / 'pyproject.toml').read_text() | |
| project = project.replace('name = "forma3d-tiny"','name = "forma3d-tiny-2"') | |
| project = project.replace('version = "0.2.0"','version = "0.3.0"') | |
| (destination / 'pyproject.toml').write_text(project) | |
| (destination / 'scripts').mkdir() | |
| for name in ('prepare_hf.py','release.py'): | |
| shutil.copyfile(source / 'scripts' / name, destination / 'scripts' / name) | |
| # This file set can reproduce the training recipe from pinned upstream. | |
| for name in ('posttrain.sh','prepare_v2.py','audit_data.py','stage_v2.py','publish_v2.py','COMMANDS.md'): | |
| shutil.copyfile(ROOT / name, destination / name) | |
| public_meta = {k:v for k,v in meta.items() if k != 'dataset'} | |
| public_meta.update({'base_model':BASE, 'base_revision':REV, | |
| 'training_method':'weights-only continuation; fresh AdamW', | |
| 'known_v1_assets_excluded':True}) | |
| torch.save({'format':1,'config':checkpoint['config'],'model':checkpoint['model'], | |
| 'step':checkpoint['step'],'metadata':public_meta}, destination / 'model.pt') | |
| (destination / 'config.json').write_text(json.dumps(checkpoint['config'],indent=2)) | |
| (destination / 'training.json').write_text(json.dumps(public_meta,indent=2)) | |
| report.update({'base_model':BASE,'base_revision':REV, | |
| 'published_model_sha256':sha(destination / 'model.pt')}) | |
| (destination / 'evaluation.json').write_text(json.dumps(report,indent=2)) | |
| for src, dst in [('sources.json','ATTRIBUTIONS.json'),('v2-audit.json','data-audit.json'), | |
| ('preparation.json','preparation.json')]: | |
| # preparation.json includes user-local paths; publish only portable fields. | |
| if src == 'preparation.json': | |
| prepared = json.loads((Path(args.data) / src).read_text()) | |
| prepared['settings'] = {k:v for k,v in prepared['settings'].items() if k not in ('out','cache')} | |
| (destination / dst).write_text(json.dumps(prepared,indent=2)) | |
| else: | |
| shutil.copyfile(Path(args.data) / src,destination / dst) | |
| shutil.copyfile(Path(args.run) / 'metrics.jsonl',destination / 'metrics.jsonl') | |
| if (ROOT / 'runs/environment.txt').exists(): | |
| lines = (ROOT / 'runs/environment.txt').read_text().splitlines() | |
| portable = [line for line in lines if ' @ file:' not in line and not line.startswith('-e ')] | |
| portable.append('# Local forma3d-tiny 0.2.0 source: '+BASE+' @ '+REV) | |
| (destination / 'environment.txt').write_text('\n'.join(portable)+'\n') | |
| datasets = sorted({r['repo'] for r in json.loads((destination / 'ATTRIBUTIONS.json').read_text())}) | |
| dataset_yaml = '\n'.join('- '+d for d in datasets) | |
| bt, ft = report['baseline_test'],report['posttrained_test'] | |
| card = f'''--- | |
| license: apache-2.0 | |
| pipeline_tag: image-to-3d | |
| base_model: {BASE} | |
| base_model_relation: finetune | |
| model_name: Forma3D Tiny 2 | |
| datasets: | |
| {dataset_yaml} | |
| tags: | |
| - pytorch | |
| - gaussian-splatting | |
| - mesh-proxy-supervision | |
| - research-prototype | |
| --- | |
| # Forma3D Tiny 2 | |
| A {meta['parameters']:,}-parameter image-to-Gaussian research model continued from | |
| {BASE} at revision `{REV}`. The optimizer starts fresh. It uses a | |
| {checkpoint['config']['grid']} cubed grid and width {checkpoint['config']['width']}. | |
| Selected checkpoint step {checkpoint['step']} from {meta['steps_requested']} completed steps. | |
| ## Training | |
| See training.json and metrics.jsonl for actual optimizer settings and validation | |
| history. Inputs are orthographic renders of centered mesh-derived Gaussian proxy | |
| clouds on black. Targets are isotropic surface samples compressed to one Gaussian | |
| per occupied grid cell. No pretrained 3D teacher was run. No natural-photo training | |
| or differentiable rendering is claimed. Asset IDs, known source groups, and exact | |
| mesh hashes from all 96 known v1 assets were excluded. Near duplicates can remain. | |
| The separate 15 percent object-group test split does not enter checkpoint selection; | |
| 20 percent of development groups supply validation. Counts are realized counts in | |
| preparation.json and data-audit.json, not assumed independent asset counts. | |
| ## Evaluation | |
| Both checkpoints were evaluated on the same new held-out proxy data. | |
| | Metric | Starting Forma3D Tiny | Selected Forma3D Tiny 2 | | |
| |---|---:|---:| | |
| | Mean test loss | {bt['loss']:.6f} | {ft['loss']:.6f} | | |
| | Mean view occupancy IoU at threshold 0.5 | {bt['occupancy_iou']:.6f} | {ft['occupancy_iou']:.6f} | | |
| Test groups: {report['test_objects']}; views: {report['test_samples']}. | |
| See evaluation.json for hashes and release gates. Metrics are view-averaged over | |
| proxy renders. They do not establish photo realism, novel-view image quality, | |
| mesh quality, texture fidelity, gameplay, or general-purpose 3D reconstruction. | |
| ## Use | |
| Install this source with Python 3.11 and `uv pip install ".[data]"` in a virtual | |
| environment, then run: | |
| ```bash | |
| image3d generate --checkpoint model.pt --image your-centered-cutout.png \\ | |
| --out results/object.ply --device mps | |
| image3d preview --ply results/object.ply --out results/preview.png | |
| ``` | |
| Output is Gaussian PLY. Inputs should match centered objects on black. See | |
| COMMANDS.md for the complete continuation recipe. This model retains the same | |
| architecture; no text-prompt conditioning or new mesh decoder was added. | |
| ## License | |
| Publisher source and weights are offered under Apache 2.0. Retain NOTICE, | |
| THIRD_PARTY.md and ATTRIBUTIONS.json. CC BY Scenario assets and CC0 Objaverse | |
| assets have their own attribution and license records in DATASETS.md. | |
| ''' | |
| (destination / 'README.md').write_text(card) | |
| sums = [sha(f)+' '+str(f.relative_to(destination)) for f in sorted(destination.rglob('*')) if f.is_file()] | |
| (destination / 'SHA256SUMS').write_text('\n'.join(sums)+'\n') | |
| print('Staged evaluated release at',destination) | |
| print('Inspect PNG files under',Path(args.run)/'inspection','before optional publication.') | |
| if __name__ == '__main__': | |
| main() | |