Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 62 additions & 2 deletions backend/python/diffusers/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@
from transformers import T5EncoderModel
from safetensors.torch import load_file

# Import LTX-2 specific utilities
try:
from diffusers.pipelines.ltx2.export_utils import encode_video as ltx2_encode_video
LTX2_AVAILABLE = True
except ImportError:
LTX2_AVAILABLE = False
ltx2_encode_video = None

_ONE_DAY_IN_SECONDS = 60 * 60 * 24
COMPEL = os.environ.get("COMPEL", "0") == "1"
XPU = os.environ.get("XPU", "0") == "1"
Expand Down Expand Up @@ -290,6 +298,20 @@ def _load_pipeline(self, request, modelFile, fromSingleFile, torchType, variant)
pipe.enable_model_cpu_offload()
return pipe

# LTX2ImageToVideoPipeline - needs img2vid flag, CPU offload, and special handling
if pipeline_type == "LTX2ImageToVideoPipeline":
self.img2vid = True
self.ltx2_pipeline = True
pipe = load_diffusers_pipeline(
class_name="LTX2ImageToVideoPipeline",
model_id=request.Model,
torch_dtype=torchType,
variant=variant
)
if not DISABLE_CPU_OFFLOAD:
pipe.enable_model_cpu_offload()
return pipe

# ================================================================
# Dynamic pipeline loading - the default path for most pipelines
# Uses the dynamic loader to instantiate any pipeline by class name
Expand Down Expand Up @@ -404,6 +426,7 @@ def LoadModel(self, request, context):
fromSingleFile = request.Model.startswith("http") or request.Model.startswith("/") or local
self.img2vid = False
self.txt2vid = False
self.ltx2_pipeline = False

# Load pipeline using dynamic loader
# Special cases that require custom initialization are handled first
Expand Down Expand Up @@ -686,7 +709,44 @@ def GenerateVideo(self, request, context):
print(f"Generating video with {kwargs=}", file=sys.stderr)

# Generate video frames based on pipeline type
if self.PipelineType == "WanPipeline":
if self.ltx2_pipeline or self.PipelineType == "LTX2ImageToVideoPipeline":
# LTX-2 image-to-video generation with audio
if not LTX2_AVAILABLE:
return backend_pb2.Result(success=False, message="LTX-2 pipeline requires diffusers.pipelines.ltx2.export_utils")

# LTX-2 uses 'image' parameter instead of 'start_image'
if request.start_image:
image = load_image(request.start_image)
kwargs["image"] = image
# Remove start_image if it was added
kwargs.pop("start_image", None)

# LTX-2 uses 'frame_rate' instead of 'fps'
frame_rate = float(fps)
kwargs["frame_rate"] = frame_rate

# LTX-2 requires output_type="np" and return_dict=False
kwargs["output_type"] = "np"
kwargs["return_dict"] = False

# Generate video and audio
video, audio = self.pipe(**kwargs)

# Convert video to uint8 format
video = (video * 255).round().astype("uint8")
video = torch.from_numpy(video)

# Use LTX-2's encode_video function which handles audio
ltx2_encode_video(
video[0],
fps=frame_rate,
audio=audio[0].float().cpu(),
audio_sample_rate=self.pipe.vocoder.config.output_sampling_rate,
output_path=request.dst,
)

return backend_pb2.Result(message="Video generated successfully", success=True)
elif self.PipelineType == "WanPipeline":
# WAN2.2 text-to-video generation
output = self.pipe(**kwargs)
frames = output.frames[0] # WAN2.2 returns frames in this format
Expand Down Expand Up @@ -727,7 +787,7 @@ def GenerateVideo(self, request, context):
else:
return backend_pb2.Result(success=False, message=f"Pipeline {self.PipelineType} does not support video generation")

# Export video
# Export video (for non-LTX-2 pipelines)
export_to_video(frames, request.dst, fps=fps)

return backend_pb2.Result(message="Video generated successfully", success=True)
Expand Down
57 changes: 57 additions & 0 deletions gallery/index.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1237,6 +1237,63 @@
cuda: true
pipeline_type: QwenImageEditPipeline
enable_parameters: num_inference_steps,image
- &ltx2
name: "ltx-2"
url: "github:mudler/LocalAI/gallery/virtual.yaml@master"
urls:
- https://huggingface.co/Lightricks/LTX-2
license: ltx-2-community-license-agreement
tags:
- diffusers
- gpu
- image-to-video
- video-generation
- audio-video
description: |
**LTX-2** is a DiT-based audio-video foundation model designed to generate synchronized video and audio within a single model. It brings together the core building blocks of modern video generation, with open weights and a focus on practical, local execution.

**Key Features:**
- **Joint Audio-Video Generation**: Generates synchronized video and audio in a single model
- **Image-to-Video**: Converts static images into dynamic videos with matching audio
- **High Quality**: Produces realistic video with natural motion and synchronized audio
- **Open Weights**: Available under the LTX-2 Community License Agreement

**Model Details:**
- **Model Type**: Diffusion-based audio-video foundation model
- **Architecture**: DiT (Diffusion Transformer) based
- **Developed by**: Lightricks
- **Paper**: [LTX-2: Efficient Joint Audio-Visual Foundation Model](https://arxiv.org/abs/2601.03233)

**Usage Tips:**
- Width & height settings must be divisible by 32
- Frame count must be divisible by 8 + 1 (e.g., 9, 17, 25, 33, 41, 49, 57, 65, 73, 81, 89, 97, 105, 113, 121)
- Recommended settings: width=768, height=512, num_frames=121, frame_rate=24.0
- For best results, use detailed prompts describing motion and scene dynamics

**Limitations:**
- This model is not intended or able to provide factual information
- Prompt following is heavily influenced by the prompting-style
- When generating audio without speech, the audio may be of lower quality

**Citation:**
```bibtex
@article{hacohen2025ltx2,
title={LTX-2: Efficient Joint Audio-Visual Foundation Model},
author={HaCohen, Yoav and Brazowski, Benny and Chiprut, Nisan and others},
journal={arXiv preprint arXiv:2601.03233},
year={2025}
}
```
overrides:
backend: diffusers
low_vram: true
parameters:
model: Lightricks/LTX-2
diffusers:
cuda: true
pipeline_type: LTX2ImageToVideoPipeline
options:
- torch_dtype:bf16
- &gptoss
name: "gpt-oss-20b"
url: "github:mudler/LocalAI/gallery/harmony.yaml@master"
Expand Down Expand Up @@ -3774,7 +3831,7 @@
- gemma3
- gemma-3
overrides:
#mmproj: gemma-3-27b-it-mmproj-f16.gguf

Check warning on line 3834 in gallery/index.yaml

View workflow job for this annotation

GitHub Actions / Yamllint

3834:6 [comments] missing starting space in comment
parameters:
model: gemma-3-27b-it-Q4_K_M.gguf
files:
Expand All @@ -3792,7 +3849,7 @@
description: |
google/gemma-3-12b-it is an open-source, state-of-the-art, lightweight, multimodal model built from the same research and technology used to create the Gemini models. It is capable of handling text and image input and generating text output. It has a large context window of 128K tokens and supports over 140 languages. The 12B variant has been fine-tuned using the instruction-tuning approach. Gemma 3 models are suitable for a variety of text generation and image understanding tasks, including question answering, summarization, and reasoning. Their relatively small size makes them deployable in environments with limited resources such as laptops, desktops, or your own cloud infrastructure.
overrides:
#mmproj: gemma-3-12b-it-mmproj-f16.gguf

Check warning on line 3852 in gallery/index.yaml

View workflow job for this annotation

GitHub Actions / Yamllint

3852:6 [comments] missing starting space in comment
parameters:
model: gemma-3-12b-it-Q4_K_M.gguf
files:
Expand All @@ -3810,7 +3867,7 @@
description: |
Gemma is a family of lightweight, state-of-the-art open models from Google, built from the same research and technology used to create the Gemini models. Gemma 3 models are multimodal, handling text and image input and generating text output, with open weights for both pre-trained variants and instruction-tuned variants. Gemma 3 has a large, 128K context window, multilingual support in over 140 languages, and is available in more sizes than previous versions. Gemma 3 models are well-suited for a variety of text generation and image understanding tasks, including question answering, summarization, and reasoning. Their relatively small size makes it possible to deploy them in environments with limited resources such as laptops, desktops or your own cloud infrastructure, democratizing access to state of the art AI models and helping foster innovation for everyone. Gemma-3-4b-it is a 4 billion parameter model.
overrides:
#mmproj: gemma-3-4b-it-mmproj-f16.gguf

Check warning on line 3870 in gallery/index.yaml

View workflow job for this annotation

GitHub Actions / Yamllint

3870:6 [comments] missing starting space in comment
parameters:
model: gemma-3-4b-it-Q4_K_M.gguf
files:
Expand Down Expand Up @@ -7028,7 +7085,7 @@
sha256: 2756551de7d8ff7093c2c5eec1cd00f1868bc128433af53f5a8d434091d4eb5a
uri: huggingface://Triangle104/Nano_Imp_1B-Q8_0-GGUF/nano_imp_1b-q8_0.gguf
- &smollm
url: "github:mudler/LocalAI/gallery/chatml.yaml@master" ## SmolLM

Check warning on line 7088 in gallery/index.yaml

View workflow job for this annotation

GitHub Actions / Yamllint

7088:59 [comments] too few spaces before comment: expected 2
name: "smollm-1.7b-instruct"
icon: https://huggingface.co/datasets/HuggingFaceTB/images/resolve/main/banner_smol.png
tags:
Expand Down Expand Up @@ -7072,7 +7129,7 @@
sha256: decd2598bc2c8ed08c19adc3c8fdd461ee19ed5708679d1c54ef54a5a30d4f33
uri: huggingface://HuggingFaceTB/SmolLM2-1.7B-Instruct-GGUF/smollm2-1.7b-instruct-q4_k_m.gguf
- &llama31
url: "github:mudler/LocalAI/gallery/llama3.1-instruct.yaml@master" ## LLama3.1

Check warning on line 7132 in gallery/index.yaml

View workflow job for this annotation

GitHub Actions / Yamllint

7132:70 [comments] too few spaces before comment: expected 2
icon: https://avatars.githubusercontent.com/u/153379578
name: "meta-llama-3.1-8b-instruct"
license: llama3.1
Expand Down
Loading