Instructions to use autotools/ai_video_studio with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- llama-cpp-python
How to use autotools/ai_video_studio with llama-cpp-python:
# !pip install llama-cpp-python from llama_cpp import Llama llm = Llama.from_pretrained( repo_id="autotools/ai_video_studio", filename="runtime/Auto Movie Reviewer/models/Phi-3.5-mini-balanced.gguf", )
llm.create_chat_completion( messages = "No input example has been defined for this model task." )
- Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use autotools/ai_video_studio with llama.cpp:
Install (macOS, Linux)
curl -LsSf https://llama.app/install.sh | sh # Start a local OpenAI-compatible server with a web UI: llama serve -hf autotools/ai_video_studio:Q4_K_M # Run inference directly in the terminal: llama cli -hf autotools/ai_video_studio:Q4_K_M
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf autotools/ai_video_studio:Q4_K_M # Run inference directly in the terminal: llama cli -hf autotools/ai_video_studio:Q4_K_M
Use pre-built binary
# Download pre-built binary from: # https://github.com/ggerganov/llama.cpp/releases # Start a local OpenAI-compatible server with a web UI: ./llama-server -hf autotools/ai_video_studio:Q4_K_M # Run inference directly in the terminal: ./llama-cli -hf autotools/ai_video_studio:Q4_K_M
Build from source code
git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-server llama-cli # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama-server -hf autotools/ai_video_studio:Q4_K_M # Run inference directly in the terminal: ./build/bin/llama-cli -hf autotools/ai_video_studio:Q4_K_M
Use Docker
docker model run hf.co/autotools/ai_video_studio:Q4_K_M
- LM Studio
- Jan
- Ollama
How to use autotools/ai_video_studio with Ollama:
ollama run hf.co/autotools/ai_video_studio:Q4_K_M
- Unsloth Studio
How to use autotools/ai_video_studio with Unsloth Studio:
Install Unsloth Studio (macOS, Linux, WSL)
curl -fsSL https://unsloth.ai/install.sh | sh # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for autotools/ai_video_studio to start chatting
Install Unsloth Studio (Windows)
irm https://unsloth.ai/install.ps1 | iex # Run unsloth studio unsloth studio -H 0.0.0.0 -p 8888 # Then open http://localhost:8888 in your browser # Search for autotools/ai_video_studio to start chatting
Using HuggingFace Spaces for Unsloth
# No setup required # Open https://huggingface.co/spaces/unsloth/studio in your browser # Search for autotools/ai_video_studio to start chatting
- Atomic Chat new
- Docker Model Runner
How to use autotools/ai_video_studio with Docker Model Runner:
docker model run hf.co/autotools/ai_video_studio:Q4_K_M
- Lemonade
How to use autotools/ai_video_studio with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull autotools/ai_video_studio:Q4_K_M
Run and chat with the model
lemonade run user.ai_video_studio-Q4_K_M
List all available models
lemonade list
| #!/usr/bin/env python3 | |
| # Copyright 2026 Xiaomi Corp. (authors: Han Zhu) | |
| # | |
| # See ../../LICENSE for clarification regarding multiple authors | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| """Batching strategies for streaming/iterable datasets. | |
| Provides length-based grouping and packing for efficient training with | |
| variable-length audio. | |
| Key classes: | |
| - ``PackingIterableDataset``: Packs multiple samples into fixed-length sequences | |
| for training. Used by ``omnivoice.training.builder`` with flex_attention. | |
| - ``StreamLengthGroupDataset``: Groups samples by length into buckets. Used by | |
| data processing scripts (e.g. ``omnivoice/scripts/``) and by | |
| ``omnivoice.training.builder`` when ``attn_implementation != "flex_attention"``. | |
| """ | |
| import bisect | |
| import logging | |
| from typing import Any, Dict, Iterator, List, Optional | |
| import numpy as np | |
| from omnivoice.data.dataset import IterableDataReader, WrappedIterableDataset | |
| class StreamLengthGroupDataset(WrappedIterableDataset): | |
| """A streaming dataset that groups samples by their lengths into buckets. | |
| By default, length is measured as audio duration in seconds from a raw | |
| waveform field. Pass a custom ``length_fn`` to use a different measure — | |
| e.g. ``lambda s: s["length"]`` for processed training data, in which case | |
| ``batch_duration`` and ``min/max_length`` should use the same units. | |
| If ``processor`` is provided, each raw sample is processed before length | |
| measurement and bucketing, and the yielded batches contain **processed** | |
| samples. This allows accurate bucketing by post-processing token length | |
| (used in the SDPA training path). | |
| """ | |
| def __init__( | |
| self, | |
| dataset: IterableDataReader, | |
| batch_duration: float, | |
| min_length: float = 0.5, | |
| max_length: float = 30.0, | |
| num_buckets: int = 20, | |
| audio_key: str = "audio", | |
| drop_last: bool = False, | |
| max_sample: Optional[int] = None, | |
| length_fn: Optional[Any] = None, | |
| processor: Optional[Any] = None, | |
| ): | |
| self.dataset = dataset | |
| self.batch_duration = batch_duration | |
| self.min_length = min_length | |
| self.max_length = max_length | |
| self.num_buckets = num_buckets | |
| self.audio_key = audio_key | |
| self.drop_last = drop_last | |
| self.max_sample = max_sample if max_sample is not None else float("inf") | |
| self.length_fn = length_fn | |
| self.processor = processor | |
| self.boundaries = np.linspace(min_length, max_length, num_buckets + 1)[1:] | |
| def set_epoch(self, epoch: int): | |
| """ | |
| Set the epoch for shuffling. | |
| """ | |
| self.dataset.set_epoch(epoch) | |
| def _get_bucket_id(self, length: float) -> int: | |
| return bisect.bisect_left(self.boundaries, length) | |
| def __iter__(self) -> Iterator[List[Dict[str, Any]]]: | |
| buckets = [[] for _ in range(self.num_buckets)] | |
| bucket_max_len = [0.0] * self.num_buckets | |
| for sample in self.dataset: | |
| if self.processor is not None: | |
| try: | |
| sample = self.processor(sample) | |
| except Exception as e: | |
| logging.warning(f"Error processing sample: {e}") | |
| continue | |
| if self.length_fn is not None: | |
| duration = self.length_fn(sample) | |
| else: | |
| audio = sample[self.audio_key] | |
| duration = audio.size(-1) / self.dataset.sample_rate | |
| if duration < self.min_length or duration > self.max_length: | |
| # logging.warning(f"Skipping sample with duration {duration:.2f}s") | |
| continue | |
| b_id = self._get_bucket_id(duration) | |
| buckets[b_id].append(sample) | |
| if duration > bucket_max_len[b_id]: | |
| bucket_max_len[b_id] = duration | |
| if ( | |
| bucket_max_len[b_id] * (len(buckets[b_id]) + 1) >= self.batch_duration | |
| or len(buckets[b_id]) >= self.max_sample | |
| ): | |
| yield buckets[b_id] | |
| buckets[b_id] = [] | |
| bucket_max_len[b_id] = 0.0 | |
| if not self.drop_last: | |
| for b_idx, bucket in enumerate(buckets): | |
| if bucket: | |
| yield bucket | |
| buckets[b_idx] = [] | |
| class PackingIterableDataset(WrappedIterableDataset): | |
| """ | |
| An IterableDataset that dynamically processes samples using a processor | |
| and packs them into batches based on the real token count. | |
| Args: | |
| dataset (Iterable): The raw dataset to process. | |
| processor (Callable): A processor to process each sample. | |
| batch_tokens (int): Maximum number of tokens per batch. | |
| """ | |
| def __init__( | |
| self, | |
| dataset: IterableDataReader, | |
| processor: Any, | |
| batch_tokens: int, | |
| ): | |
| self.dataset = dataset | |
| self.processor = processor | |
| self.batch_tokens = batch_tokens | |
| self.skip_batches = 0 | |
| def set_epoch(self, epoch: int): | |
| """ | |
| Set the epoch for shuffling. | |
| """ | |
| self.dataset.set_epoch(epoch) | |
| def __iter__(self) -> Iterator[List[Dict[str, Any]]]: | |
| current_batch = [] | |
| current_token_count = 0 | |
| for raw_sample in self.dataset: | |
| # Process the sample using the processor | |
| try: | |
| processed_sample = self.processor(raw_sample) | |
| except Exception as e: | |
| logging.warning(f"Error processing sample {raw_sample}: {e}") | |
| continue | |
| sample_length = processed_sample["length"] | |
| if sample_length > self.batch_tokens: | |
| continue | |
| # Check if adding this sample exceeds the batch token limit | |
| if current_token_count + sample_length > self.batch_tokens: | |
| # Yield the current batch and start a new one | |
| yield current_batch | |
| current_batch = [] | |
| current_token_count = 0 | |
| # Add the processed sample to the current batch | |
| current_batch.append(processed_sample) | |
| current_token_count += sample_length | |
| # Yield the last batch if it's not empty | |
| if current_batch: | |
| yield current_batch | |