Skip to main content

Training Parameters

Beyond presets, you can control individual parameters of the reconstruction pipeline. Parameters are split into two tiers: stable (won’t change between API versions) and advanced (may evolve).

Per-tier parameter envelopes

Each preset runs on a different class of GPU, and several cost-bearing knobs are bounded by what that GPU can physically run. These are not artificial product caps — the ceiling on each tier is the physics of your tier’s GPU. A fast-tier L4 can’t densify 15M gaussians; an ultra-tier H100 can. Override a knob beyond its tier’s envelope and the request is rejected with a 422, never silently clamped — the error names the cheapest tier that unlocks the value so you can decide whether to bump up. A rejected request returns the violation(s) under error.details:
These envelopes apply to the custom preset too — a custom request is checked against the standard envelope unless you set its preset to a higher tier. Cluster-cleanup toggles (output.cluster_*) carry no per-tier limit; they’re available on every tier. training.cap_max (the MCMC Gaussian budget) is not accepted yet: the API refuses it as an unknown key (exposed: false in packages/core/src/params.ts).

Stable parameters

These are the parameters you’ll use most often. They’re part of the v1 API contract.

preset

The base preset to use. See Quality Presets for details.

sfm.backend

The structure-from-motion engine used to estimate camera poses from your images. See SfM Backends for a detailed comparison.
sfm.backend currently only takes effect when sfm.options is also provided (SfmRequest.from_api_payload in sfm_backends/configs.py). Sent on its own, the value is accepted but the pipeline runs the default engine. The pipeline also registers none_arkit, which copies a finished pose model instead of solving one. No API input writes that model, so its SfM step fails, and the scene with it (refunded; NoneArkitBackend.run). To send ARKit poses, see SfM Backends.
For backward compatibility the API also accepts the legacy short-names glomap, colmap, and none — they resolve to colmap_sift_glomap, colmap_sift_glomap, and none_arkit respectively. Prefer the canonical names in new code; colmap will warn and may be removed in a future release.

sfm.matcher

How image pairs are matched during SfM. exhaustive compares every pair (best for photo sets and small/medium scenes), sequential assumes ordered frames (fastest for video). The pipeline picks one from your input type: photos get exhaustive, video gets sequential.
SfM does not read this top-level field: it is checked against your tier (the fast tier allows only sequential), then ignored. On standard and above, choose the matcher with sfm.options.matcher (see sfm.options).

sfm.max_image_size

Maximum image dimension in pixels for training. Images larger than this are downscaled before training. Set to 0 for no downscaling. SfM extracts features at sfm.options.max_image_size instead (default 1600), whatever this field says. The range above is the global bound; your tier narrows it further (see Per-tier parameter envelopes) — in practice only the fast tier reaches down to 256, and only ultra accepts the 0 full-resolution sentinel.

sfm.options

Options for the SfM engine, forwarded to the Python pipeline and validated there. This is where SfM settings take effect: the keys are listed under colmap_sift_glomap in SfM Backends. Sending sfm.options (even {}) also makes the pipeline read sfm.backend. Unknown keys are rejected by the backend’s Pydantic model with a clear error message (ColmapSiftGlomapOptions in sfm_backends/configs.py).

enable_lod

Whether to produce Level-of-Detail chunks alongside the main output. LOD chunks let the web viewer stream large scenes progressively (faster first paint, smoother camera motion) but increase processing time and storage. Send it in the POST /v1/scenes/{id}/process body. Scene creation checks it against your tier but does not keep it (createScene in api/src/lib/scenes.ts).

training.iterations

Number of training iterations. More iterations generally means higher quality but longer processing time. Diminishing returns kick in around 15K for most scenes. The effective range is gated by your tier — see Per-tier parameter envelopes (e.g. standard allows 3,000–10,000; push higher by choosing quality or ultra).

output.formats

Accepted, no effect. Values ("sog", "ply") are validated, but the pipeline doesn’t read them: every scene gets SOG and PLY, and SPZ on a best-effort basis (_upload_to_r2 in pipeline/storage/upload.py). See Output Formats.

output.compute_metrics

Checked against your tier (fast can’t set it to true), but the pipeline doesn’t read it: holdout metrics (psnr_holdout, ssim_holdout) are computed whenever output.holdout_ratio is above 0.

Advanced parameters

Advanced parameters are experimental and may change between API versions. Use them when you know what you’re doing.

training.sh_degree

Spherical harmonics degree for view-dependent color. Higher values capture more view-dependent effects (like reflections) but increase model size. 3 is the standard for most scenes. sh_degree: 4 is gated to the quality and ultra tiers — see Per-tier parameter envelopes.

Accepted, no effect

These four are validated against the ranges below, then ignored: _stage_train (pipeline/training/impl.py) doesn’t pass them on, and train_and_export (train_gsplat.py) uses fixed values. Sending them changes neither the result nor the price.

training.ssim_weight

Weight of the SSIM loss term relative to L1 loss. The total loss is (1 - ssim_weight) * L1 + ssim_weight * SSIM. Higher values prioritize structural similarity.

training.strategy

Densification strategy that controls how Gaussians are added, removed, and refined during training.
  • "default" (production path) — gradient-driven split/clone/prune via gsplat’s DefaultStrategy with AbsGrad. Gaussian count grows naturally based on per-splat gradient magnitudes.
  • "mcmc" — Markov Chain Monte Carlo / SGLD-style densification (Kheradmand et al. NeurIPS 2024). Steers the gaussian count toward a hard cap via opacity/scale L1 regularization and Langevin noise injection. Tends to produce more gaussians (3× typical) and stronger photometric detail, at the cost of larger output files.
MCMC is required if you enable training.post_processing = "ppisp" (see below). The two are commonly used together for iPhone walkthroughs with variable lighting.

training.post_processing

Optional photometric correction module that fits per-camera/per-frame ISP parameters (exposure, white balance, vignette, color) during training. Reduces floaters and color drift that the gaussians would otherwise absorb into their spherical-harmonics coefficients. PPISP (NVIDIA’s Physically-Plausible ISP, Jan 2026) is most valuable for uncontrolled captures: phone walkthroughs with auto-exposure crossing varied lighting (indoor → window → outdoor), or photo zips from multiple devices. It shows little gain on controlled-lighting captures (fixed-exposure DSLR work).
PPISP requires training.strategy: "mcmc" — combining with the default strategy will be rejected with a ValueError from the trainer. Enabling PPISP also implies the larger file sizes and slower viewer-side render of MCMC.

output.holdout_ratio

Fraction of images held out for metric evaluation. Above 0, the held-out images give psnr_holdout and ssim_holdout, whatever compute_metrics says. Set to 0 to use all images for training (no metrics).

Common recipes

Quick preview for testing

High quality with metrics

Maximum detail, slower training

High iteration counts and sh_degree: 4 are gated to the ultra tier (its H100 has the headroom). Start from the ultra preset rather than custom so the request stays inside the per-tier envelope:

Match every pair of video frames

Video is matched sequentially by default. To compare every pair of frames instead (slower; standard and above), set the matcher in sfm.options:
Start with a preset and only override specific parameters once you understand how they affect your particular scenes. The defaults work well for the vast majority of captures.
Hitting the limits of what the parameters here can do — e.g. you need more iterations, higher resolution, or a tunable not exposed yet? Email [email protected] and tell us about your use case.