| # DinoVision paper artifact protocol |
|
|
| This experiment is a deployment case study for Meganeura, not an additional |
| cell in the paper's matched Meganeura/PyTorch performance-portability matrix. |
| Its target claim is narrower and complementary; it is admitted only after the |
| correctness and device gates below pass: |
|
|
| > One decoder definition is trained through Meganeura autodiff on an RTX GPU |
| > and instantiated for inference, joined to a DINOv3 encoder, through the same |
| > compiler and Vulkan runtime on an Adreno-based Android XR device. The |
| > application shares Blade's graphics context and queue with inference. |
|
|
| The artifact must distinguish that demonstrated claim from hypotheses about |
| decoder quality, f16 arithmetic, zero-copy integration, or camera perception. |
|
|
| ## Frozen revisions and assets |
|
|
| A paper freeze should use clean revisions. During development, every run must |
| instead retain an exact source snapshot in addition to its base revisions. |
| The evidence bundle records: |
|
|
| - full Git revisions for DinoVision and Meganeura, the Blade revision selected |
| by Cargo, cleanliness state, and any exact source snapshot needed to |
| reproduce a dirty development run; |
| - `Cargo.lock`, `cargo tree`, Rust/NDK/ADB versions, GPU/driver, Horizon build, |
| refresh configuration, thermal state, and all runtime toggle values; |
| - SHA-256 hashes for the upstream DINO checkpoint and each decoder; |
| - the immutable dataset manifest and the exact command line; |
| - raw timing or per-image records, followed by separately generated summary |
| tables and figures. |
|
|
| The canonical DINO checkpoint remains an upstream dependency rather than being |
| duplicated. Meta's DINOv3 License permits redistribution only under that |
| agreement and requires a copy of it, a prominent “Built with DINOv3” notice, |
| and acknowledgment in resulting research. The artifact links to the gated |
| canonical model and preserves its hash. Decoder weights are treated |
| conservatively as DINOv3-derived: their model repository carries the DINOv3 |
| agreement and notice rather than presenting the weights as unconditionally |
| MIT-licensed. The DinoVision source remains MIT. Generated decoder weights are |
| published with their architecture, depth, resolution, dataset-manifest hash, |
| and training metadata. |
|
|
| ## Dataset validity |
|
|
| Generate `dataset.json` with `tools/make_dataset_manifest.py`. A `group` is a |
| leakage boundary: one headset capture session, room/lighting traversal, or |
| photo collection. A group may occur in exactly one of `train`, `validation`, |
| and `test`. Identical file hashes may not cross splits. |
|
|
| The paper-quality dataset should contain at least: |
|
|
| - an Imagenette/photo training source; |
| - multiple independent headset capture sessions for training; |
| - held-out capture sessions from different trajectories and lighting for |
| validation and test; |
| - a separately reported held-out photo split, so domain adaptation is not |
| hidden inside one aggregate. |
|
|
| Sequential camera frames must never be randomly divided across splits. |
| Create each capture group under its own immutable session name by writing that |
| name into the device's `capture` flag before launching the app, for example |
| `echo room-a-01 > /data/local/tmp/dinovision/capture`. The app refuses to |
| overwrite a non-empty session directory. |
|
|
| ## Reconstruction evaluation |
|
|
| Use `examples/evaluate_decoder.rs`. It verifies all input hashes and emits |
| per-image MSE, MAE, PSNR, and RGB SSIM, plus global PSNR and distributions. |
| The sample PNGs place the target on the left and reconstruction on the right; |
| the same directory retains raw preprocessed patches, the full encoder output, |
| the spatial decoder input, and decoder output for numerical cross-device |
| comparison. |
|
|
| The deployment artifact repeats its selected `3 layers @ 224` cell with three |
| decoder initializations. If the report retains comparative depth or resolution |
| claims, extend that into this matched matrix, again with three seeds per cell: |
|
|
| | Encoder | Resolution | Decoder | Purpose | |
| |---|---:|---|---| |
| | 12 layers | 224 | early two-stage blend | official final representation | |
| | 3 layers | 224 | early two-stage blend | deployed latency choice | |
| | 3 layers | 240 | retargeted and retrained | test the tail-waste hypothesis end to end | |
|
|
| If the report retains claims about L1, constant learning rate, or the number of |
| blend stages, those become matched ablations under the same manifests and |
| seeds. Otherwise they are described as implementation choices, not findings. |
|
|
| Example: |
|
|
| ```powershell |
| python tools/make_dataset_manifest.py ` |
| --root C:\Data\dinovision ` |
| --output experiments\dataset.json ` |
| --entry train photo imagenette-train imagenette\train ` |
| --entry train capture room-a captures\room-a ` |
| --entry test capture room-b captures\room-b |
| |
| cargo run --release --example evaluate_decoder -- ` |
| --manifest experiments\dataset.json ` |
| --model model.safetensors --decoder decoder.bin ` |
| --split test --layers 3 --output artifacts\quality-3l-224.json |
| ``` |
|
|
| Training uses a deterministic, seed-controlled shuffle and writes its decoder, |
| diagnostic strip, and `training.json` into the requested output directory: |
|
|
| ```powershell |
| cargo run --release --example train_decoder -- ` |
| experiments\dataset.json model.safetensors ` |
| 12000 2500 3 224 0 artifacts\train-3l-224-seed0 |
| ``` |
|
|
| ## Timing validity |
|
|
| Isolated native benchmarks and live-XR co-tenancy are separate experiments. |
|
|
| For isolated kernel/encoder timings: |
|
|
| - use five or more untimed warmups and at least 20 retained synchronized |
| samples; |
| - report median, IQR, minimum, maximum, and every raw sample; |
| - stabilize the headset in one power/display state before the matrix; |
| - randomize or bracket variants rather than relying on monotonic clock ramp; |
| - repeat the matrix in at least three fresh processes. |
|
|
| For the XR application, retain every `DINOVISION_APP_JSON` record and report: |
|
|
| - application render-submission rate; |
| - each eye's independent update rate and the lower of the two rates; |
| - per-worker wall latency, explicitly not capture-to-photon latency; |
| - mono/stereo, chunk count, inference interval, display refresh, and duration. |
|
|
| Sweep `submission_chunks = 1, 2, 4, 8, 12, 16` at a fixed interval in the |
| predeclared order `4, 16, 1, 12, 2, 8`, rather than coupling chunk count to |
| startup or thermal drift. Report both isolated throughput cost and live |
| render/update tradeoff. Run long enough to expose sustained thermal behavior. |
| App submission rate must not be called compositor or display rate. |
|
|
| ## Correctness |
|
|
| Before performance or quality results are admitted: |
|
|
| 1. run the Hugging Face reference comparison and retain its tensors/output; |
| 2. run the same fixed raw image and weights through `evaluate_decoder` on RTX |
| and Adreno, retaining `*-patches.f32`, `*-encoder.f32`, `*-features.f32`, |
| and `*-reconstruction.f32`; |
| 3. report relative output L2, maximum absolute error, and per-token cosine; |
| 4. confirm decoder output agreement across the two devices; |
| 5. run `cargo test --workspace --all-targets`, with the real-weight semantic |
| test enabled rather than silently skipped. |
|
|
| Use `tools/compare_f32.py` for each host/device tensor pair. It records both |
| input hashes, relative L2, cosine similarity, mean/max absolute error, and the |
| explicit pass thresholds rather than relying on a console-only comparison. |
|
|
| ## Audited command sequence |
|
|
| The wrappers refuse to merge results into non-empty directories. On a device |
| with historical DinoVision data, the recovery pull is deliberately the first |
| device operation: |
|
|
| ```powershell |
| .\tools\run_decoder_matrix.ps1 ` |
| -Manifest C:\Data\manifests\imagenette2-320.json ` |
| -Model C:\Models\dinov3-vits16\model.safetensors ` |
| -OutputRoot C:\Runs\dinovision-quality |
| |
| .\tools\build_android_artifacts.ps1 ` |
| -OutputDir C:\Runs\dinovision-android-build |
| |
| .\tools\pull_quest_artifacts.ps1 ` |
| -OutputDir C:\Runs\quest-recovery-before-corrected-run |
| ``` |
|
|
| Generate the host half of the fixed-frame comparison with the preselected |
| seed-0 decoder, then run the checked device half: |
|
|
| ```powershell |
| cargo run --release --example evaluate_decoder -- ` |
| --manifest C:\Data\correctness\manifests\correctness-224.json ` |
| --model C:\Models\dinov3-vits16\model.safetensors ` |
| --decoder C:\Runs\dinovision-quality\3l224-seed0\decoder.bin ` |
| --split test --layers 3 --size 224 ` |
| --output C:\Data\correctness\host-seed0\quality.json --samples 1 |
| |
| .\tools\run_cross_device_correctness.ps1 ` |
| -OutputDir C:\Runs\quest-correctness ` |
| -RecoveryManifest C:\Runs\quest-recovery-before-corrected-run\recovery_manifest.json ` |
| -Binary C:\Runs\dinovision-android-build\evaluate_decoder ` |
| -CorrectnessRoot C:\Data\correctness ` |
| -HostSampleDir C:\Data\correctness\host-seed0\quality_samples ` |
| -Model C:\Models\dinov3-vits16\model.safetensors ` |
| -Decoder C:\Runs\dinovision-quality\3l224-seed0\decoder.bin |
| ``` |
|
|
| Only after that comparison passes are timing runs admissible: |
|
|
| ```powershell |
| .\tools\run_quest_bench.ps1 ` |
| -OutputDir C:\Runs\quest-isolated ` |
| -RecoveryManifest C:\Runs\quest-recovery-before-corrected-run\recovery_manifest.json ` |
| -Binary C:\Runs\dinovision-android-build\bench ` |
| -Condition live-worn -Processes 3 -Iterations 20 |
| |
| python .\tools\summarize_bench.py ` |
| --records C:\Runs\quest-isolated\benchmark-records.json ` |
| --metadata C:\Runs\quest-isolated\benchmark-metadata.json ` |
| --output-json C:\Runs\quest-isolated\benchmark-summary.json ` |
| --output-markdown C:\Runs\quest-isolated\benchmark-summary.md |
| |
| .\tools\run_xr_sweep.ps1 ` |
| -OutputDir C:\Runs\quest-live-xr ` |
| -RecoveryManifest C:\Runs\quest-recovery-before-corrected-run\recovery_manifest.json ` |
| -Apk C:\Runs\dinovision-android-build\dinovision_xr.apk ` |
| -Model C:\Models\dinov3-vits16\model.safetensors ` |
| -Decoder C:\Runs\dinovision-quality\3l224-seed0\decoder.bin |
| ``` |
|
|
| The XR summary consumes the six `chunks-*-records.json` files as repeated |
| `--records` arguments. The sweep backs up and restores every runtime toggle |
| and both preexisting weight files; it never enables camera capture. |
|
|
| ## Interpretation rules |
|
|
| - A microbenchmark may explain a hypothesis, but only a profile of the |
| deployed graph may assign wall time to an operation class. |
| - f16 weight storage says nothing conclusive about unimplemented f16 |
| arithmetic. |
| - The 240-pixel encoder result is not an end-to-end result until its decoder, |
| preprocessing, readback, and rendering path are included. |
| - Direct GPU output is future work until output lifetime, EMA, layout, and |
| synchronization are implemented and measured. |
| - Stereo fusion, comfort, camera rate, and capture-to-photon claims require |
| timestamps/calibration or are labeled single-user observations. |
|
|