# Environment Variables FastVideo reads environment variables for expert switches, debugging, profiling, and the settings that launchers such as `torchrun` provide. This page is the policy for those variables. The contract test `fastvideo/tests/contract/test_env_policy.py` enforces the policy in the unit CI lane, and the coding-agent skill `.agents/skills/env-var-conventions/SKILL.md` points here. When the policy changes, update this page and the contract test in the same pull request. ## Rules 1. **Register every FastVideo variable in `fastvideo/envs.py`.** Each entry declares a type, a default, a category, and a description. Variables that other tools own (CUDA, NCCL, PyTorch, launchers) are not registered; code reads them directly with `os.environ.get("NAME")`, and the name must be in the external-variable allowlist (`EXTERNAL_ALLOWLIST` in the contract test). When FastVideo sets such a variable for the other tool, it calls `envs.set_external`, `envs.setdefault_external`, or `envs.unset_external`, and the name must be in `EXTERNAL_WRITE_ALLOWLIST`. 2. **Read with `envs.NAME.get()`, write with `envs.NAME.set()`, and change a value in tests with `envs.NAME.override()`.** Each type has one parsing rule. A value that the rule rejects raises `fastvideo.envs.EnvVarError` instead of falling back to the default. 3. **Name FastVideo variables with the `FASTVIDEO_` prefix.** The second word states the purpose where one applies: `ENABLE_`, `DISABLE_`, `USE_`, `FORCE_`, `DEBUG_`, `TEST_`. 4. **Keep a renamed variable as a deprecated alias until the next minor release.** Setting the old name logs a warning. Delete a variable that no code reads, and list it in `DEPRECATED_VARIABLES` so that setting it logs a warning. 5. **Give each setting one source: an argument or an environment variable.** Settings that users change per deployment are arguments (CLI or YAML). Expert switches, emergency off switches, and debugging and test switches are environment variables. 6. **Read variables inside functions.** `envs.NAME.get()` runs when the function runs, so a changed value takes effect without re-importing a module. Module level, class bodies, decorators, and default argument values run at import time. 7. **Do not write the environment to pass values between parts of FastVideo.** Pass an argument instead. Tests use `envs.NAME.override()`. ## Field types | Class | Value type | Parsing rule | | ------------ | ---------------- | ----------------------------------------------------------------------------------- | | `EnvBool` | `bool` | `1`, `true`, `yes`, `on` are true; `0`, `false`, `no`, `off`, and `""` are false. | | | | Case-insensitive; surrounding whitespace is ignored. | | `EnvInt` | `int` | `int(value)` | | `EnvFloat` | `float` | `float(value)` | | `EnvStr` | `str` or `None` | The raw string. A `None` default means that the variable has no default. | | `EnvPath` | `str` or `None` | The raw string with a leading `~` expanded. | | `EnvChoice` | `str` | Stripped and lower-cased, then checked against the declared `choices`. | A default can be a zero-argument function; `get()` calls it on each read while the variable is unset. The path roots use this to follow `XDG_CONFIG_HOME` and `XDG_CACHE_HOME`. Using a field without a method, as in `if envs.FASTVIDEO_FA4:`, raises `TypeError`. ## Add a variable 1. Declare the variable in the matching section of `fastvideo/envs.py`: ```python FASTVIDEO_DEBUG_MY_STAGE = EnvBool(False, category="debug", doc="Log the inputs of MyStage.") ``` The category is one of the values in `envs.CATEGORIES`. 2. Read the variable inside a function: ```python import fastvideo.envs as envs def forward(self, batch): if envs.FASTVIDEO_DEBUG_MY_STAGE.get(): logger.info("MyStage inputs: %s", batch.keys()) ``` 3. Regenerate the table at the end of this page: ```bash python fastvideo/tests/contract/test_env_policy.py ``` 4. Run the contract test: ```bash pytest fastvideo/tests/contract/test_env_policy.py ``` In a test, change the value with `override`, which restores the previous value on exit: ```python with envs.FASTVIDEO_DEBUG_MY_STAGE.override(True): run_stage() ``` ## Rename or remove a variable To rename a variable, declare it under the new name and list the old name in `deprecated_names`: ```python FASTVIDEO_LTX2_USE_DISTILLED_SIGMAS = EnvBool(True, category="sampling", doc="...", deprecated_names=("LTX2_USE_DISTILLED_SIGMAS", )) ``` `get()` reads an old name only when the new name is unset, and logs a warning once. Update the uses of the old name in `examples/`, `scripts/`, `docs/`, `apps/`, and the tests in the same pull request. Delete the old name in the next minor release. To remove a variable that no code reads, delete its entry and add the name to `DEPRECATED_VARIABLES` in `fastvideo/envs.py` with a reason. `FastVideoArgs` calls `envs.warn_deprecated_variables()`, which logs a warning for each listed variable that is set. Delete the entry in the next minor release. ## What the contract test checks The test parses every Python file under `fastvideo/`, including `fastvideo/tests/`, with Python's `ast` module. It skips `fastvideo/third_party/`, which is copied from upstream projects, and the registry `fastvideo/envs.py`. It does not check `apps/`, `examples/`, `scripts/`, `fastvideo-kernel/`, or `docs/`. It reports each violation as `: `: | Kind | Code that triggers it | Fix | | ------------------ | ------------------------------------------------------------ | -------------------------------------------- | | `read` | `os.getenv`, `os.environ.get`, `os.environ[...]`, or | Register the variable and call | | | `"NAME" in os.environ` with a name outside the allowlist, or | `envs.NAME.get()`. For a variable that | | | with a name built at runtime (``) | another tool owns, add it to | | | | `EXTERNAL_ALLOWLIST` with a reason. | | `write` | `os.environ[...] = ...`, `setdefault`, `pop`, `del`, | Pass an argument instead. In tests, use | | | `os.putenv`, `os.unsetenv`, `monkeypatch.setenv`/`delenv`, | `envs.NAME.override()`. For a variable that | | | or an `envs.*_external` call with a name outside | another tool reads, call an | | | `EXTERNAL_WRITE_ALLOWLIST` | `envs.*_external` helper and add the name to | | | | `EXTERNAL_WRITE_ALLOWLIST` with a reason. | | `whole-environ` | `os.environ.copy()`, `dict(os.environ)`, iteration, | Read the specific variables that the code | | | `mock.patch.dict(os.environ, ...)`, `os.environ.update` | needs. | | `bare-field` | A registry field used without calling one of its methods, | Call `envs.NAME.get()`. | | | as in `envs.NAME == "auto"` or `getter = envs.NAME.get` | | | `import-time-read` | `envs.NAME.get()` outside a function | Move the read into the function that uses | | | | the value. | | `prefix` | A registry entry without the `FASTVIDEO_` prefix | Rename the variable and keep the old name in | | | | `deprecated_names`. | | `unread` | A registry entry that no code reads with `get()` or | Delete the variable and add it to | | | `is_set()` | `DEPRECATED_VARIABLES`. | The test recognizes `os` imported under another name, `from os import environ, getenv`, and a name held in a module-level string constant. Code that reaches the environment through `importlib` or `getattr(os, "environ")` is left to code review. The test also checks that every registry entry has a category from `envs.CATEGORIES` and a description, and that the table at the end of this page matches the registry. **Known violations.** `KNOWN_VIOLATIONS` in the contract test lists the violations that existed when the policy was introduced. The list only shrinks. A violation that is not in the list fails the test. A listed violation that no longer exists also fails the test, so the fixing pull request deletes its entry. ## Registered variables | Variable | Type | Default | Category | Description | | ---------------------------------------------------------- | ------------------------------ | ----------------------------------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `FASTVIDEO_CONFIG_ROOT` | path | computed | path | Root directory for FastVideo configuration files, at runtime and at installation. Defaults to ~/.config/fastvideo, or $XDG_CONFIG_HOME/fastvideo when XDG_CONFIG_HOME is set. | | `FASTVIDEO_CACHE_ROOT` | path | computed | path | Root directory for FastVideo cache files. Defaults to ~/.cache/fastvideo, or $XDG_CACHE_HOME/fastvideo when XDG_CACHE_HOME is set. | | `FASTVIDEO_REASON1_WEIGHTS_PATH` | str | unset | path | Local path or Hugging Face id of Reason1 weights to load instead of the checkpoint's own. | | `FASTVIDEO_HOST_IP` | str | `""` | distributed | IP address of this node when the node has several network interfaces. Set it on each node for multi-node inference. | | `FASTVIDEO_LOOPBACK_IP` | str | `""` | distributed | Loopback IP address to use instead of the detected one. | | `FASTVIDEO_RAY_PER_WORKER_GPUS` | float | `1.0` | distributed | GPUs per Ray worker. A fraction lets Ray schedule several actors on one GPU, so other actors can share the GPUs with FastVideo. | | `FASTVIDEO_NCCL_SO_PATH` | str | unset | distributed | Path to the NCCL library file. Needed because the nccl>=2.19 that PyTorch ships has a bug (https://github.com/NVIDIA/nccl/issues/1234). | | `FASTVIDEO_HCCL_SO_PATH` | str | unset | distributed | Path to the HCCL library file on Ascend NPUs. Deprecated names: `HCCL_SO_PATH`. | | `FASTVIDEO_WORKER_MULTIPROC_METHOD` | one of spawn, fork, forkserver | `spawn` | distributed | Multiprocessing start method for worker processes. | | `FASTVIDEO_ULYSSES_A2A` | one of off, auto | `off` | distributed | Sequence-parallel all-to-all backend. off uses the NCCL path in DistributedAutograd.AllToAll4D. auto uses the fused NVLink kernel when the group is a load-store accessible mesh of 2, 4, 6, or 8 ranks in eager execution, and the NCCL path otherwise. | | `FASTVIDEO_CONFIGURE_LOGGING` | bool | `1` | logging | Configure logging at import. When true, FastVideo uses its default logging configuration or the file in FASTVIDEO_LOGGING_CONFIG_PATH. | | `FASTVIDEO_LOGGING_CONFIG_PATH` | str | unset | logging | Path to a JSON logging configuration file. | | `FASTVIDEO_LOGGING_LEVEL` | str | `INFO` | logging | Default logging level. | | `FASTVIDEO_LOGGING_PREFIX` | str | `""` | logging | Prefix prepended to every log message. | | `FASTVIDEO_STAGE_LOGGING` | bool | `0` | logging | Log the time that each pipeline stage takes. | | `FASTVIDEO_ATTENTION_BACKEND` | str | unset | attention | Attention backend, as an AttentionBackendEnum name such as TORCH_SDPA, FLASH_ATTN, VIDEO_SPARSE_ATTN, SAGE_ATTN, or SAGE_ATTN_THREE. FastVideoArgs uses it when FastVideoArgs.attention_backend is unset. | | `FASTVIDEO_FA4` | bool | `0` | attention | The FLASH_ATTN backend uses FlashAttention-4 (flash_attn.cute) instead of FA3 or FA2. | | `FASTVIDEO_MINIMAX_H3_FA4_PACKED_VARLEN` | bool | `0` | attention | MiniMax-H3 dense DiT self-attention uses the FlashAttention-4 packed-varlen entry point. This changes the floating-point reduction order, so it is an inference-only opt-in. | | `FASTVIDEO_VSA_SM100A` | bool | `0` | attention | VIDEO_SPARSE_ATTN_H3 sends no-grad tile-64 forwards to the data-center Blackwell (sm_100a) kernel. fastvideo-kernel reads the same variable with the same rule. | | `FASTVIDEO_NVFP4_FA4` | bool | `0` | attention | FlashAttention-4 quantizes Q and K to NVFP4. An explicit nvfp4_fa4 attention implementation argument takes precedence. | | `FASTVIDEO_DISABLE_ATTENTION_COMPILE` | bool | `1` | attention | Keep attention forward out of torch.compile graphs (torch.compiler.disable). Set it to 0 to let attention constructed under that setting be traced. Setting it explicitly to true also blocks regional compile. | | `FASTVIDEO_MLX_WINDOW` | int | `0` | attention | MLX FastWan windowed attention size in tokens. 0 uses full attention. | | `FASTVIDEO_MLX_WINDOW_SINK` | int | `0` | attention | Number of sink tokens that MLX windowed attention always attends to. | | `FASTVIDEO_INFERENCE_TORCH_COMPILE` | bool | `0` | performance | Compile each DiT transformer block with fullgraph torch.compile at inference. Same as FastVideoArgs.inference_torch_compile=True. | | `FASTVIDEO_VAE_PARALLEL_DECODE` | bool | `0` | performance | MiniMax-H3 VAE decode splits its temporal chunks across the sequence-parallel ranks instead of running serially on the output rank. Same as FastVideoArgs.vae_parallel_decode=True. | | `FASTVIDEO_VAE_PARALLEL_ENCODE` | bool | `0` | performance | MiniMax-H3 reference-video VAE encode splits its temporal chunks across the sequence-parallel ranks. Same as FastVideoArgs.vae_parallel_encode=True. | | `FASTVIDEO_VAE_PARALLEL_DECODE_STRATEGY` | str | unset | performance | Collective that moves chunks in parallel VAE decode: gather (used when unset) or all_gather. | | `FASTVIDEO_MINIMAX_H3_FUSIONS` | str | `""` | performance | MiniMax-H3 inference-only Triton fusions: all, 1, or a comma-separated subset of modulate,qknorm_rope,swiglu. Empty, 0, or none keeps the eager implementation. | | `FASTVIDEO_FSDP2_AUTOWRAP` | bool | `0` | performance | FSDP2 shards modules by parameter count instead of the model's shard conditions. Not supported by self-forcing distillation. | | `FASTVIDEO_FSDP2_MIN_PARAMS` | int | `10000000` | performance | Minimum parameter count of a module that FASTVIDEO_FSDP2_AUTOWRAP shards. | | `FASTVIDEO_MLX_COMPILE` | bool | `0` | performance | Compile the MLX DiT forward with mx.compile. | | `FASTVIDEO_MLX_FAST_NORM` | bool | `0` | performance | Use MLX fast normalization kernels. | | `FASTVIDEO_MLX_DQ_GEMM` | str | `1` | performance | MLX dequantized GEMM for affine-quantized weights: 0 turns it off, 1 uses the measured minimum row count, and an integer sets the minimum row count. | | `FASTVIDEO_LTX2_VAE_CHANNELS_LAST_3D` | bool | `1` | performance | LTX-2 VAE uses the channels_last_3d memory format. | | `FASTVIDEO_LTX2_DISABLE_AUDIO_AUTOCAST` | bool | `1` | performance | LTX-2 audio decoding runs without CUDA autocast. Deprecated names: `LTX2_DISABLE_AUDIO_AUTOCAST`. | | `FASTVIDEO_FLUX2_DISABLE_BF16_REDUCED_PRECISION_REDUCTION` | bool | `0` | performance | Flux denoising disables reduced-precision reductions in bf16 matmuls, which tightens accumulation for the 4-step Klein model. | | `FASTVIDEO_FFMPEG_BIN` | str | `ffmpeg` | output | ffmpeg executable used to save video with audio. | | `FASTVIDEO_VIDEO_CODEC` | str | `libx264` | output | ffmpeg video codec for saved videos. | | `FASTVIDEO_NVENC_PRESET` | str | `p1` | output | NVENC preset when the codec is an \*_nvenc codec. | | `FASTVIDEO_NVENC_TUNE` | str | `ull` | output | NVENC tune option. | | `FASTVIDEO_NVENC_RC` | str | `constqp` | output | NVENC rate-control mode. | | `FASTVIDEO_NVENC_QP` | str | `28` | output | NVENC quantization parameter. | | `FASTVIDEO_NVENC_BF` | str | `0` | output | NVENC number of B-frames. | | `FASTVIDEO_X264_PRESET` | str | `ultrafast` | output | x264 preset for non-NVENC codecs. | | `FASTVIDEO_OUTPUT_PIX_FMT` | str | `yuv420p` | output | ffmpeg pixel format for saved videos. | | `FASTVIDEO_NVTX_PROFILE` | bool | `0` | profiling | Emit NVTX ranges for external profilers such as Nsight Systems. | | `FASTVIDEO_TORCH_PROFILER_DIR` | path | unset | profiling | Enables the torch profiler and sets the directory for its traces. Must be an absolute path. | | `FASTVIDEO_TORCH_PROFILER_RECORD_SHAPES` | bool | `0` | profiling | Torch profiler records shapes. | | `FASTVIDEO_TORCH_PROFILER_WITH_PROFILE_MEMORY` | bool | `0` | profiling | Torch profiler profiles memory. | | `FASTVIDEO_TORCH_PROFILER_WITH_STACK` | bool | `0` | profiling | Torch profiler captures stacks. Costs about 1.5x runtime and 1.4x trace size. | | `FASTVIDEO_TORCH_PROFILER_WITH_FLOPS` | bool | `0` | profiling | Torch profiler profiles FLOPs. | | `FASTVIDEO_TORCH_PROFILE_REGIONS` | str | `""` | profiling | Comma-separated profiler regions to record. The torch profiler requires at least one region. | | `FASTVIDEO_TRACE_ACTIVATIONS` | bool | `0` | debug | Enable activation trace hooks. | | `FASTVIDEO_TRACE_LAYERS` | str | `""` | debug | Regex filter for traced module names. Empty means all. | | `FASTVIDEO_TRACE_STATS` | str | `abs_mean,sum` | debug | Comma-separated activation statistics dumped for each output tensor. | | `FASTVIDEO_TRACE_OUTPUT` | str | `/tmp/fv_trace_.jsonl` | debug | JSONL path for activation traces. The literal <pid> is replaced at runtime. | | `FASTVIDEO_TRACE_STEPS` | str | `""` | debug | Comma-separated denoising step indices. Empty means all. | | `FASTVIDEO_H3_VSA_PROBE` | str | unset | debug | Output directory for the VSA-H3 attention-mass probe, which writes one .pt file per step, layer, and rank. Keeps the model out of regional compile. | | `FASTVIDEO_LTX2_GEMMA_LOG` | str | `""` | debug | Log file for LTX-2 Gemma text-encoder hidden states, used by parity tests. Deprecated names: `LTX2_FASTVIDEO_GEMMA_LOG`. | | `FASTVIDEO_COSMOS25_LOG_KNOBS` | bool | `0` | debug | Log the Cosmos 2.5 latent-preparation conditioning inputs. | | `FASTVIDEO_CFG_GATE_STEP` | float | `1.0` | sampling | CFG gating fraction in [0, 1]. Steps before len(timesteps) \* X run the conditional and unconditional forwards; later steps reuse the cached difference. 1.0 disables gating. | | `FASTVIDEO_LTX2_USE_DISTILLED_SIGMAS` | bool | `1` | sampling | LTX-2 uses the distilled sigma schedule when FastVideoArgs.ltx2_use_distilled_sigmas is also true. Deprecated names: `LTX2_USE_DISTILLED_SIGMAS`. | | `FASTVIDEO_EVAL_CACHE` | path | computed | eval | Cache directory for evaluation models and datasets. Defaults to $FASTVIDEO_CACHE_ROOT/eval. | | `FASTVIDEO_PHYSICS_IQ_BUCKET_URL` | str | `https://storage.googleapis.com/physics-iq-benchmark` | eval | Base URL of the Physics-IQ benchmark bucket. | | `FASTVIDEO_VBENCH_FULL_INFO_JSON` | str | unset | eval | Path to VBench_full_info.json, used instead of the vendored copy. Deprecated names: `VBENCH_FULL_INFO_JSON`. | | `FASTVIDEO_FVD_REF_FEATURES` | str | unset | eval | Cached reference-feature file for the FVD metric. | | `FASTVIDEO_FAD_REF_FEATURES` | str | unset | eval | Cached reference-feature file for the audio Frechet distance metric. | | `FASTVIDEO_TEST_LTX2_OVERFIT_DATA_DIR` | str | `data/cats` | test | Raw data directory for preprocess_ltx2_overfit.py. Deprecated names: `LTX2_OVERFIT_DATA_DIR`. | | `FASTVIDEO_TEST_LTX2_OVERFIT_CAPTION_JSON` | str | `videos2caption_1_sample.json` | test | Caption file, relative to the raw data directory. Deprecated names: `LTX2_OVERFIT_CAPTION_JSON`. | | `FASTVIDEO_TEST_LTX2_OVERFIT_VIDEO_SUBDIR` | str | `video` | test | Video subdirectory, relative to the raw data directory. Deprecated names: `LTX2_OVERFIT_VIDEO_SUBDIR`. | | `FASTVIDEO_TEST_LTX2_OVERFIT_OUTPUT_DIR` | str | `data/ltx2_overfit_preprocessed` | test | Output directory for preprocess_ltx2_overfit.py. Deprecated names: `LTX2_OVERFIT_OUTPUT_DIR`. | | `FASTVIDEO_TEST_LTX2_OVERFIT_MODEL` | str | `FastVideo/LTX2-Distilled-Diffusers` | test | Model repository whose encoders preprocess_ltx2_overfit.py uses. Deprecated names: `LTX2_OVERFIT_MODEL`. | | `FASTVIDEO_TEST_LTX2_OVERFIT_NUM_COPIES` | int | `4` | test | Number of copies of the overfit sample in the parquet file. Deprecated names: `LTX2_OVERFIT_NUM_COPIES`. | | `FASTVIDEO_TEST_KANDINSKY5_OVERFIT_DATA_DIR` | str | `data/kandinsky5_overfit` | test | Raw data directory for preprocess_kandinsky5_overfit.py. Deprecated names: `KANDINSKY5_OVERFIT_DATA_DIR`. | | `FASTVIDEO_TEST_KANDINSKY5_OVERFIT_OUTPUT_DIR` | str | `data/kandinsky5_overfit_preprocessed` | test | Output directory for preprocess_kandinsky5_overfit.py. Deprecated names: `KANDINSKY5_OVERFIT_OUTPUT_DIR`. | Variables that FastVideo no longer reads; setting one logs a warning: | Deprecated variable | Reason | | ----------------------------------------- | ---------------- | | `FASTVIDEO_TARGET_DEVICE` | no code reads it | | `FASTVIDEO_USE_PRECOMPILED` | no code reads it | | `FASTVIDEO_RINGBUFFER_WARNING_INTERVAL` | no code reads it | | `FASTVIDEO_ENGINE_ITERATION_TIMEOUT_S` | no code reads it | | `FASTVIDEO_SERVER_DEV_MODE` | no code reads it | | `FASTVIDEO_TEST_DYNAMO_FULLGRAPH_CAPTURE` | no code reads it | | `FASTVIDEO_TRACE_FUNCTION` | no code reads it |