Difix3D

repository·main·Indexed 23 days ago

https://github.com/nv-tlabs/difix3d

A framework for improving 3D reconstructions using single-step diffusion models. It includes Difix for single-step artifact removal, Difix3D for progressive 3D updates integrated with nerfstudio and gsplat, and Difix3D+ for real-time post-rendering enhancement. The package provides the Difix model class for diffusion-based processing and the DifixPipeline for text-to-image generation with support for LoRA, IP Adapters, and FreeU.

Tokens
4.7K
Snippets
10
Records
23
Agent score
79%

What's inside difix3d

  1. Quickstart DifixPipeline with diffusers

    main

    You can use the DifixPipeline via the diffusers library for single-step diffusion-based artifact removal.

    Standard Usage: Load the pretrained model nvidia/difix and pass an input image with a prompt (e.g., "remove degradation").

    With Reference Image: To guide the denoising process, use the nvidia/difix_ref model and provide a ref_image to the pipeline call.

    from pipeline_difix import DifixPipeline
    from diffusers.utils import load_image
    
    # Standard usage
    pipe = DifixPipeline.from_pretrained("nvidia/difix", trust_remote_code=True)
    pipe.to("cuda")
    
    input_image = load_image("assets/example_input.png")
    prompt = "remove degradation"
    
    output_image = pipe(prompt, image=input_image, num_inference_steps=1, timesteps=[199], guidance_scale=0.0).images[0]
    output_image.save("example_output.png")
  2. Fine-tune Difix3D with nerfstudio

    main

    To use Difix3D with nerfstudio, first install the nerfstudio environment from the examples/nerfstudio directory. Then, use the ns-train difix3d command to start finetuning on a specific scene.

    # Setup nerfstudio
    cd examples/nerfstudio
    pip install -e .
    cd ../..
    
    # Run finetuning
    SCENE_ID=032dee9fb0a8bc1b90871dc5fe950080d0bcd3caf166447f44e60ca50ac04ec7
    DATA=DATA_DIR/${SCENE_ID}
    DATA_FACTOR=4
    CKPT_PATH=CKPR_DIR/${SCENE_ID}/nerfacto/nerfstudio_models/step-000029999.ckpt
    OUTPUT_DIR=outputs/difix3d/nerfacto/${SCENE_ID}
    
    CUDA_VISIBLE_DEVICES=0 ns-train difix3d \
        --data ${DATA} --pipeline.model.appearance-embed-dim 0 --pipeline.model.camera-optimizer.mode off --save_only_latest_checkpoint False --vis viewer \
        --output_dir ${OUTPUT_DIR} --experiment_name ${SCENE_ID} --timestamp '' --load-checkpoint ${CKPT_PATH} \
        --max_num_iterations 30000 --steps_per_eval_all_images 0 --steps_per_eval_batch 0 --steps_per_eval_image 0 --steps_per_save 2000 --viewer.quit-on-train-completion True \
        nerfstudio-data --orientation-method none --center_method none --auto-scale-poses False --downscale_factor ${DATA_FACTOR} --eval_mode filename
  3. Use Difix3D+ for real-time post-rendering

    main

    Difix3D+ uses the Difix model as a post-processing step at render time to enhance novel views and recover sharp details that reconstruction methods might miss. Run inference on rendered images using src/inference_difix.py.

    python src/inference_difix.py \
        --model_path "checkpoints/model.pkl" \
        --input_image "PATH_TO_IMAGES" \
        --prompt "remove degradation" \
        --output_dir "outputs/difix3d+" \
        --timestep 199
  4. Train Difix model (Single or Multiple GPUs)

    main

    Training is performed using accelerate launch running src/train_difix.py.

    Single GPU Training: Use the --dataset_path flag to point to your JSON data and configure hyperparameters like --max_train_steps, --resolution, and loss weights (--lambda_lpips, --lambda_l2, --lambda_gram).

    Multi-GPU Training: Set NUM_NODES and NUM_GPUS environment variables and use the --multi_gpu flag with accelerate launch.

    # Single GPU
    accelerate launch --mixed_precision=bf16 src/train_difix.py \
        --output_dir=./outputs/difix/train \
        --dataset_path="data/data.json" \
        --max_train_steps 10000 \
        --resolution=512 --learning_rate 2e-5 \
        --train_batch_size=1 --dataloader_num_workers 8 \
        --enable_xformers_memory_efficient_attention \
        --checkpointing_steps=1000 --eval_freq 1000 --viz_freq 100 \
        --lambda_lpips 1.0 --lambda_l2 1.0 --lambda_gram 1.0 --gram_loss_warmup_steps 2000 \
        --report_to "wandb" --tracker_project_name "difix" --tracker_run_name "train" --timestep 199
  5. Fine-tune Difix3D with gsplat

    main

    To use Difix3D with gsplat, ensure gsplat is installed following its official instructions. Use the examples/gsplat/simple_trainer_difix3d.py script to run the finetuning process.

    SCENE_ID=032dee9fb0a8bc1b90871dc5fe950080d0bcd3caf166447f44e60ca50ac04ec7
    DATA=DATA_DIR/${SCENE_ID}/gaussian_splat
    DATA_FACTOR=4
    CKPT_PATH=CKPT_DIR/${SCENE_ID}/ckpts/ckpt_29999_rank0.pt
    OUTPUT_DIR=outputs/difix3d/gsplat/${SCENE_ID}
    
    CUDA_VISIBLE_DEVICES=0 python examples/gsplat/simple_trainer_difix3d.py default \
        --data_dir ${DATA} --data_factor ${DATA_FACTOR} \
        --result_dir ${OUTPUT_DIR} --no-normalize-world-space --test_every 1 --ckpt ${CKPT_PATH}
  6. Configure guidance_rescale to prevent overexposure

    main

    When using certain noise schedules (like zero terminal SNR), the guidance_scale can cause overexposure in generated images. You can mitigate this by providing a guidance_rescale value to the __call__ method. This factor mixes the guidance results with the original results to maintain better image quality.

    Parameter:

    • guidance_rescale (float): A factor used to rescale the noise prediction based on the guidance scale. Defaults to 0.0 (no rescaling).
  7. Run Difix inference

    main

    To run inference on a single image using a trained checkpoint, place your model_*.pkl in the checkpoints directory and execute src/inference_difix.py.

    python src/inference_difix.py \
        --model_path "checkpoints/model.pkl" \
        --input_image "assets/example_input.png" \
        --prompt "remove degradation" \
        --output_dir "outputs/difix" \
        --timestep 199
  8. Prepare data for Difix training

    main

    Datasets for training the single-step Difix model must be provided in a JSON format containing train and test splits. Each entry in a split is keyed by a {data_id} and contains paths to the input image, target image, reference image, and the associated prompt.

    {
      "train": {
        "{data_id}": {
          "image": "{PATH_TO_IMAGE}",
          "target_image": "{PATH_TO_TARGET_IMAGE}",
          "ref_image": "{PATH_TO_REF_IMAGE}",
          "prompt": "remove degradation"
        }
      },
      "test": {
        "{data_id}": {
          "image": "{PATH_TO_IMAGE}",
          "target_image": "{PATH_TO_TARGET_IMAGE}",
          "ref_image": "{PATH_TO_REF_IMAGE}",
          "prompt": "remove degradation"
        }
      }
    }
  9. Organize data for Difix3D progressive updates

    main

    Difix3D requires a specific directory structure for scenes. Each {SCENE_ID} must contain a colmap directory (with sparse reconstruction files) and an images directory, along with multi-scale image directories (images_2, images_4, images_8).

    DATA_DIR/
    ├── {SCENE_ID}
    │   ├── colmap
    │   │   ├── sparse
    │   │   │   └── 0
    │   │   │       ├── cameras.bin
    │   │   │       ├── database.db
    │   │   │       └── ...
    │   ├── images
    │   │   ├── image_train_000001.png
    │   │   ├── image_train_000002.png
    │   │   ├── ...
    │   │   ├── image_eval_000200.png
    │   │   ├── image_eval_000201.png
    │   │   └── ...
    │   ├── images_2
    │   ├── images_4
    │   └── images_8
  10. Run image generation with DifixPipeline.__call__

    main

    The __call__ method is the primary entry point for generating images using the Difix pipeline. It supports text-to-image, image-to-image (via ref_image), and IP-Adapter workflows.

    Key Arguments

    • prompt (str or List[str]): The text prompt(s) to guide generation.
    • image (PipelineImageInput): The input image for image-to-image tasks.
    • ref_image (PipelineImageInput): An optional reference image.
    • num_inference_steps (int, default: 50): Number of denoising steps.
    • guidance_scale (float, default: 7.5): Higher values encourage adherence to the prompt.
    • negative_prompt (str or List[str]): Prompts for what to exclude.
    • guidance_rescale (float, default: 0.0): Rescale factor to fix overexposure when using zero terminal SNR.
    • ip_adapter_image (PipelineImageInput): Optional image input for IP-Adapter functionality.
    • output_type (str, default: `
  11. Initialize the Difix model

    main

    The Difix class is the primary entry point for the model. It initializes a diffusion-based model using sd-turbo components (tokenizer, text encoder, VAE, and UNet). It supports loading from a pretrained path or initializing with random weights and adding LoRA adapters to the VAE for skip-connection learning.

    Key arguments:

    • pretrained_name: Name of the pretrained model (e.g., from Hugging Face).
    • pretrained_path: Local path to a checkpoint file. If provided, it loads the UNet, VAE (with LoRA), and optimizer states.
    • ckpt_folder: Directory for checkpoints.
    • lora_rank_vae: The rank r for the VAE LoRA adapter (default is 4).
    • mv_unet: If True, uses mv_unet.UNet2DConditionModel instead of the standard diffusers UNet.
    • timestep: The diffusion timestep to use (default is 999).