---
title: preprocess_cosmos_overfit
---

<div class="python-reference">
<a id="fastvideo.pipelines.preprocess.preprocess_cosmos_overfit-classes"></a>
<a id="fastvideo.pipelines.preprocess.preprocess_cosmos_overfit-functions"></a>
<a id="fastvideo.pipelines.preprocess.preprocess_cosmos_overfit"></a>
<p>Preprocess Cosmos-Predict2 overfit data into parquet format.</p>
<p>Encodes videos with the Cosmos (Wan-style) VAE and captions with the
single T5 Large text encoder into the t2v parquet schema expected by
the training framework.</p>
<h2>Usage</h2>
<p>CUDA_VISIBLE_DEVICES=0 python fastvideo/pipelines/preprocess/preprocess_cosmos_overfit.py</p>
<h2 id="fastvideo.pipelines.preprocess.preprocess_cosmos_overfit.T5LargeConfig"><code>fastvideo.pipelines.preprocess.preprocess_cosmos_overfit.T5LargeConfig</code></h2>
<pre class="doc-signature"><code>T5LargeConfig(arch_config: TextEncoderArchConfig = T5LargeArchConfig(), prefix: str = &#x27;t5&#x27;, quant_config: QuantizationConfig | None = None, lora_config: Any | None = None, is_chat_model: bool = False, treat_empty_as_dot: bool = False, *, _resolved_attention_backend: AttentionBackendEnum | None = None, chat_template_enable_thinking: bool = False)</code></pre>
<p>T5 Large configuration for your specific model.</p>

<h2 id="fastvideo.pipelines.preprocess.preprocess_cosmos_overfit.BaseEncoderOutput"><code>fastvideo.pipelines.preprocess.preprocess_cosmos_overfit.BaseEncoderOutput</code></h2>
<pre class="doc-signature"><code>BaseEncoderOutput(last_hidden_state: torch.FloatTensor | None = None, pooler_output: torch.FloatTensor | None = None, hidden_states: tuple&#91;torch.FloatTensor, ...&#93; | None = None, attentions: tuple&#91;torch.FloatTensor, ...&#93; | None = None, attention_mask: torch.Tensor | None = None)</code></pre>


<h2 id="fastvideo.pipelines.preprocess.preprocess_cosmos_overfit.t5_large_postprocess_text"><code>fastvideo.pipelines.preprocess.preprocess_cosmos_overfit.t5_large_postprocess_text</code></h2>
<pre class="doc-signature"><code>t5_large_postprocess_text(outputs: BaseEncoderOutput) -&gt; torch.Tensor</code></pre>
<p>Postprocess T5 Large text encoder outputs for Cosmos pipeline.</p>
<p>Return raw last_hidden_state without truncation/padding.</p>
<h2 id="fastvideo.pipelines.preprocess.preprocess_cosmos_overfit.maybe_download_model"><code>fastvideo.pipelines.preprocess.preprocess_cosmos_overfit.maybe_download_model</code></h2>
<pre class="doc-signature"><code>maybe_download_model(model_name_or_path: str, local_dir: str | None = None, download: bool = True, revision: str | None = None, allow_patterns: list&#91;str&#93; | None = None) -&gt; str</code></pre>
<p>Check if the model path is a Hugging Face Hub model ID and download it if needed.</p>
<p>Supports an "umbrella" repo layout where a single HF repo holds multiple
pipeline variants under sibling subfolders. If the input is shaped as
<code>org/repo/subfolder</code> (i.e. a non-existent local path with 3+ slash-
separated components and at least one segment that does not look like a
posix-absolute path), treat the first two components as the HF repo id
and the remainder as a subfolder; only the subfolder's blobs are
downloaded, and the returned local path points inside that subfolder.</p>
<h3>Parameters</h3>
<dl>
<dt><code>model_name_or_path: str</code></dt><dd><p>Local path, Hugging Face Hub model ID, or
<code>org/repo/subfolder</code> umbrella-repo reference.</p></dd>
<dt><code>local_dir: str | None</code></dt><dd><p>Local directory to save the model</p></dd>
<dt><code>download: bool</code></dt><dd><p>Whether to download the model from Hugging Face Hub</p></dd>
<dt><code>revision: str | None</code></dt><dd><p>Optional immutable Hub revision.</p></dd>
<dt><code>allow_patterns: list[str] | None</code></dt><dd><p>Optional Hub glob patterns limiting downloaded files.
Local paths are returned unchanged. For umbrella references, the
patterns are interpreted relative to the selected subfolder.</p></dd>
</dl>
<h3>Returns</h3>
<dl>
<dt><code>str</code></dt><dd><p>Local path to the model (or to the subfolder inside the snapshot).</p></dd>
</dl>
<h2 id="fastvideo.pipelines.preprocess.preprocess_cosmos_overfit.load_video"><code>fastvideo.pipelines.preprocess.preprocess_cosmos_overfit.load_video</code></h2>
<pre class="doc-signature"><code>load_video(path: str, num_frames: int) -&gt; torch.Tensor</code></pre>
<p>Load video as [1, C, T, H, W] in [-1, 1].</p>
<details><summary>Source</summary><pre><code>def load_video(path: str, num_frames: int) -&gt; torch.Tensor:
    &quot;&quot;&quot;Load video as &#91;1, C, T, H, W&#93; in &#91;-1, 1&#93;.&quot;&quot;&quot;
    cap = cv2.VideoCapture(path)
    frames: list&#91;np.ndarray&#93; = &#91;&#93;
    while len(frames) &lt; num_frames:
        ret, frame = cap.read()
        if not ret:
            break
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        frames.append(frame)
    cap.release()

    if len(frames) &lt; num_frames:
        # Repeat last frame to fill
        while len(frames) &lt; num_frames:
            frames.append(frames&#91;-1&#93;)

    frames = frames&#91;:num_frames&#93;
    video = np.stack(frames, axis=0)
    video = torch.from_numpy(video).float()
    video = video / 127.5 - 1.0  # &#91;0,255&#93; -&gt; &#91;-1,1&#93;
    video = video.permute(3, 0, 1, 2).unsqueeze(0)  # &#91;1,C,T,H,W&#93;
    return video</code></pre></details>
<h2 id="fastvideo.pipelines.preprocess.preprocess_cosmos_overfit.main"><code>fastvideo.pipelines.preprocess.preprocess_cosmos_overfit.main</code></h2>
<pre class="doc-signature"><code>main() -&gt; None</code></pre>

<details><summary>Source</summary><pre><code>def main() -&gt; None:
    device = torch.device(&quot;cuda:0&quot;)
    model_path = maybe_download_model(MODEL_REPO)

    os.makedirs(OUTPUT_DIR, exist_ok=True)

    # Load captions
    with open(os.path.join(DATA_DIR, &quot;videos2caption.json&quot;)) as f:
        caption_data = json.load(f)

    # --- Load VAE ---
    # Cosmos-Predict2-2B ships a Wan-style VAE; vae/config.json declares
    # `_class_name: AutoencoderKLWan`, so diffusers can load it directly.
    print(&quot;Loading Cosmos VAE (AutoencoderKLWan)...&quot;)
    from diffusers import AutoencoderKLWan
    vae = AutoencoderKLWan.from_pretrained(
        model_path,
        subfolder=&quot;vae&quot;,
        torch_dtype=torch.float16,
    ).to(device).eval()
    print(f&quot;VAE loaded (&#123;sum(p.numel() for p in vae.parameters())/1e6:.0f&#125;M)&quot;)

    # --- Load T5 Large text encoder ---
    print(&quot;Loading T5 Large text encoder...&quot;)
    from transformers import AutoTokenizer, T5EncoderModel

    t5_cfg = T5LargeConfig()
    tok_kwargs = dict(t5_cfg.tokenizer_kwargs)
    tokenizer = AutoTokenizer.from_pretrained(os.path.join(model_path, &quot;tokenizer&quot;))
    text_encoder = T5EncoderModel.from_pretrained(
        os.path.join(model_path, &quot;text_encoder&quot;),
        torch_dtype=torch.bfloat16,
    ).to(device).eval()

    # --- Process each video ---
    records = &#91;&#93;
    for idx, item in enumerate(caption_data):
        video_name = item&#91;&quot;path&quot;&#93;
        record_id = f&quot;&#123;idx:04d&#125;_&#123;video_name&#125;&quot;
        caption = item&#91;&quot;cap&quot;&#93;&#91;0&#93;
        video_path = os.path.join(DATA_DIR, &quot;videos&quot;, video_name)

        print(f&quot;\nProcessing: &#123;video_name&#125;&quot;)
        print(f&quot;  Caption: &#123;caption&#91;:80&#93;&#125;...&quot;)

        # Encode video
        video = load_video(video_path, NUM_FRAMES).to(device=device, dtype=torch.float16)
        print(f&quot;  Video shape: &#123;video.shape&#125;&quot;)

        with torch.no_grad():
            latent_dist = vae.encode(video).latent_dist
            # Cast to fp32 — dataloader hardcodes np.float32
            latent = latent_dist.mean.squeeze(0).float().cpu()
        print(f&quot;  Latent shape: &#123;latent.shape&#125;&quot;)

        # Encode text with T5
        with torch.no_grad():
            inputs = tokenizer(caption, **tok_kwargs).to(device)
            outputs = text_encoder(**inputs)
            enc_out = BaseEncoderOutput(
                last_hidden_state=outputs.last_hidden_state,
                attention_mask=inputs&#91;&quot;attention_mask&quot;&#93;,
            )
            # &#91;1, max_len, 1024&#93;, zeros beyond real length
            t5_embed = t5_large_postprocess_text(enc_out).squeeze(0)
            # Trim to real sequence length so dataloader&#x27;s pad() builds
            # the correct attention mask.
            real_len = int(inputs&#91;&quot;attention_mask&quot;&#93;.sum().item())
            text_embedding = t5_embed&#91;:real_len&#93;.float().cpu()  # &#91;seq, 1024&#93;
        print(f&quot;  Text embedding shape: &#123;text_embedding.shape&#125;&quot;)

        record = &#123;
            &quot;id&quot;: record_id,
            &quot;vae_latent_bytes&quot;: latent.numpy().tobytes(),
            &quot;vae_latent_shape&quot;: list(latent.shape),
            &quot;vae_latent_dtype&quot;: str(latent.dtype).replace(&quot;torch.&quot;, &quot;&quot;),
            &quot;text_embedding_bytes&quot;: text_embedding.numpy().tobytes(),
            &quot;text_embedding_shape&quot;: list(text_embedding.shape),
            &quot;text_embedding_dtype&quot;: str(text_embedding.dtype).replace(&quot;torch.&quot;, &quot;&quot;),
            &quot;file_name&quot;: video_name,
            &quot;caption&quot;: caption,
            &quot;media_type&quot;: &quot;video&quot;,
            &quot;width&quot;: MAX_WIDTH,
            &quot;height&quot;: MAX_HEIGHT,
            &quot;num_frames&quot;: NUM_FRAMES,
            &quot;duration_sec&quot;: NUM_FRAMES / TRAIN_FPS,
            &quot;fps&quot;: TRAIN_FPS,
        &#125;
        records.append(record)

    # Clean up encoders
    del text_encoder, tokenizer, vae

    # Write parquet
    table = pa.table(
        &#123;k: &#91;r&#91;k&#93; for r in records&#93;
         for k in records&#91;0&#93;&#125;,
        schema=pyarrow_schema_t2v,
    )
    output_path = os.path.join(OUTPUT_DIR, &quot;data_00000.parquet&quot;)
    pq.write_table(table, output_path)
    print(f&quot;\nWrote &#123;len(records)&#125; records to &#123;output_path&#125;&quot;)

    # Extract first frame from first video as V2W conditioning image
    import cv2
    first_video = os.path.join(DATA_DIR, &quot;videos&quot;, caption_data&#91;0&#93;&#91;&quot;path&quot;&#93;)
    cap = cv2.VideoCapture(first_video)
    ret, frame = cap.read()
    cap.release()
    cond_frame_path = os.path.join(OUTPUT_DIR, &quot;cond_frame.png&quot;)
    if ret:
        cv2.imwrite(cond_frame_path, frame)
        print(f&quot;Saved conditioning frame to &#123;cond_frame_path&#125;&quot;)

    # Write validation prompts for callback
    # Wrap in &quot;data&quot; key — ValidationDataset expects field=&quot;data&quot;
    # Use &quot;caption&quot; field — ValidationDataset aliases it to &quot;prompt&quot;
    # Include image_path for V2W conditioning during validation
    val_prompts = &#123;
        &quot;data&quot;: &#91;&#123;
            &quot;caption&quot;: item&#91;&quot;cap&quot;&#93;&#91;0&#93;,
            &quot;image_path&quot;: &quot;cond_frame.png&quot;,
        &#125; for item in caption_data&#93;
    &#125;
    val_path = os.path.join(OUTPUT_DIR, &quot;validation_prompts.json&quot;)
    with open(val_path, &quot;w&quot;) as f:
        json.dump(val_prompts, f, indent=2)
    print(f&quot;Wrote validation prompts to &#123;val_path&#125;&quot;)

    print(&quot;\nDone! Use data_path: &quot; + OUTPUT_DIR + &quot; in training config.&quot;)</code></pre></details>
</div>
