Files
Keval MorabiaandClaude Sonnet 4.6 80a77d1cc0 Add LTX-2 third-party license notices for legal compliance (#1226)
## Summary

LTX-2 (`ltx-core`, `ltx-pipelines`, `ltx-trainer`) is a third-party
dependency developed and provided by Lightricks. It is governed by the
[LTX Community License
Agreement](https://github.com/Lightricks/LTX-2/blob/main/LICENSE),
**not** the Apache 2.0 license that covers NVIDIA Model Optimizer. Per
legal guidance, all integration points must clearly surface this to
users.

- Add `[!WARNING]` license notice blocks at the top of all LTX-2-related
READMEs (`examples/diffusers`, `examples/diffusers/distillation`,
`examples/windows/diffusers/qad_example`)
- Add `warnings.warn(UserWarning)` at every LTX package import site in
Python files, covering both top-level and lazy imports:
  - `examples/diffusers/distillation/distillation_trainer.py`
  - `examples/diffusers/quantization/calibration.py`
  - `examples/diffusers/quantization/pipeline_manager.py`
-
`examples/windows/diffusers/qad_example/sample_example_qad_diffusers.py`
  - `modelopt/torch/export/diffusers_utils.py`
  - `modelopt/torch/quantization/plugins/diffusion/ltx2.py`
- Add license notice comment to `requirements.txt` files that list LTX
packages, so the obligation is visible at install time
- Update `.github/CODEOWNERS` so all `requirements*.txt` files (covering
variants like `requirements-dev.txt`) are owned by
`@NVIDIA/modelopt-setup-codeowners` regardless of location, via a
last-match-wins rule

**Design notes:**
- For library files (`diffusers_utils.py`, `ltx2.py`), the warning is
placed at the lazy import site inside functions — it fires only when
LTX-2 code paths are actually invoked, not at module import time, to
avoid polluting non-LTX users
- For example entry-point scripts that are LTX-2-only, the warning fires
at module load time (after all imports, to satisfy ruff E402)

## Test plan

- [ ] Confirm `pre-commit run --all-files` passes (ruff, mypy,
markdownlint, bandit all clean)
- [ ] Verify warning appears at runtime when running an LTX-2
quantization or distillation example
- [ ] Confirm non-LTX code paths (FLUX, SDXL, SD3) do not emit the
warning

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Documentation**
* Added third-party license notices across documentation and
requirements files clarifying LTX-2 packages are governed by the LTX
Community License Agreement rather than NVIDIA Model Optimizer's Apache
2.0 license.

* **Chores**
  * Updated code ownership configuration for requirements files.
* Added runtime warnings to notify when LTX-2 dependencies are accessed.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Keval Morabia <28916987+kevalmorabia97@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 11:04:29 +05:30
..

LTX-2 Distillation Training with ModelOpt

Warning

Third-Party License Notice — LTX-2

LTX-2 is a third-party model and set of packages developed and provided by Lightricks. LTX-2 is not covered by the Apache 2.0 license that governs NVIDIA Model Optimizer.

By installing and using LTX-2 packages (ltx-core, ltx-pipelines, ltx-trainer) with NVIDIA Model Optimizer, you must comply with the LTX Community License Agreement.

Any derivative models or fine-tuned weights produced from LTX-2 using NVIDIA Model Optimizer (including quantized or distilled checkpoints) remain subject to the LTX Community License Agreement and are not covered by Apache 2.0.

Knowledge distillation for LTX-2 DiT models using NVIDIA ModelOpt. A frozen teacher guides a trainable student through a combined loss:

L_total = α × L_task + (1-α) × L_distill

Currently supported:

  • Quantization-Aware Distillation (QAD) — student uses ModelOpt fake quantization

Planned:

  • Sparsity-Aware Distillation (SAD) — student uses ModelOpt sparsity

Installation

# From the distillation example directory
cd examples/diffusers/distillation

# Install Model-Optimizer (from repo root)
pip install -e ../../..

# Install all dependencies (ltx-trainer, ltx-core, ltx-pipelines, omegaconf)
pip install -r requirements.txt

Quick Start

1. Prepare Your Dataset

Use the ltx-trainer preprocessing to extract latents and text embeddings:

python -m ltx_trainer.preprocess \
    --input_dir /path/to/videos \
    --output_dir /path/to/preprocessed \
    --model_path /path/to/ltx2/checkpoint.safetensors

2. Configure

Copy and edit the example config:

cp configs/distillation_example.yaml configs/my_experiment.yaml

Key settings to update:

model:
  model_path: "/path/to/ltx2/checkpoint.safetensors"
  text_encoder_path: "/path/to/gemma/model"

data:
  preprocessed_data_root: "/path/to/preprocessed/data"

distillation:
  distillation_alpha: 0.5       # 1.0 = pure task loss, 0.0 = pure distillation
  quant_cfg: "FP8_DEFAULT_CFG"  # or INT8_DEFAULT_CFG, NVFP4_DEFAULT_CFG, null

# IMPORTANT: disable ltx-trainer's built-in quantization
acceleration:
  quantization: null

3. Run Training

Single GPU

python distillation_trainer.py --config configs/my_experiment.yaml

Multi-GPU (Single Node) with Accelerate

accelerate launch \
    --config_file configs/accelerate/fsdp.yaml \
    --num_processes 8 \
    distillation_trainer.py --config configs/my_experiment.yaml

Multi-node Training with Accelerate

To launch on multiple nodes, make sure to set the following environment variables on each node:

  • NUM_NODES: Total number of nodes
  • GPUS_PER_NODE: Number of GPUs per node
  • NODE_RANK: Unique rank/index of this node (0-based)
  • MASTER_ADDR: IP address of the master node (rank 0)
  • MASTER_PORT: Communication port (e.g., 29500)

Then run this (on every node):

accelerate launch \
    --config_file configs/accelerate/fsdp.yaml \
    --num_machines $NUM_NODES \
    --num_processes $((NUM_NODES * GPUS_PER_NODE)) \
    --machine_rank $NODE_RANK \
    --main_process_ip $MASTER_ADDR \
    --main_process_port $MASTER_PORT \
    distillation_trainer.py --config configs/my_experiment.yaml

Config overrides can be passed via CLI using dotted notation:

accelerate launch ... distillation_trainer.py \
    --config configs/my_experiment.yaml \
    ++distillation.distillation_alpha=0.6 \
    ++distillation.quant_cfg=INT8_DEFAULT_CFG \
    ++optimization.learning_rate=1e-5

Configuration Reference

Calibration

Before training begins, calibration runs full denoising inference to collect activation statistics for accurate quantizer scales. This is cached as a step-0 checkpoint and reused on subsequent runs.

Parameter Default Description
calibration_prompts_file null Text file with one prompt per line. Use the HuggingFace dataset 'Gustavosta/Stable-Diffusion-Prompts' if null.
calibration_size 128 Number of prompts (each runs a full denoising loop)
calibration_n_steps 30 Denoising steps per prompt
calibration_guidance_scale 4.0 CFG scale (should match inference-time)

Checkpoint Resume

Parameter Default Description
resume_from_checkpoint null "latest" to auto-detect, or explicit path
must_save_by null Minutes after which to save and exit (for Slurm time limits)
restore_quantized_checkpoint null Restore a pre-quantized model (skips calibration)
save_quantized_checkpoint null Path to save the final quantized model

Custom Quantization Configs

To define custom quantization configs, add entries to CUSTOM_QUANT_CONFIGS in distillation_trainer.py:

CUSTOM_QUANT_CONFIGS["MY_FP8_CFG"] = {
    "quant_cfg": mtq.FP8_DEFAULT_CFG["quant_cfg"],
    "algorithm": "max",
}

Then reference it in your YAML: quant_cfg: MY_FP8_CFG.