{"record":{"id":"503668174736a0b4","repo":"unslothai/unsloth","slug":"path-path-name-carries-have-s-2f-s-of-audio-f","errorCode":null,"errorMessage":"{Path(path).name} carries {have_s:.2f}s of audio for a {want_s:.2f}s clip. MiniMax-H3 denoises video and audio together, so padding the rest with silence would train the adapter to stop generating sound. Use a clip whose soundtrack runs its full length.","messagePattern":"(.+?) carries (.+?)s of audio for a (.+?)s clip\\. MiniMax-H3 denoises video and audio together, so padding the rest with silence would train the adapter to stop generating sound\\. Use a clip whose soundtrack runs its full length\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"studio/backend/core/training/diffusion_h3_clips.py","lineNumber":463,"sourceCode":"                chunks.append(block)\n                have += block.shape[0]\n            if have >= target_samples:\n                break\n        if have < target_samples:\n            # Only when the stream ran out: the resampler holds a partial block back, and that\n            # tail is what the pad allowance below is measured against. After an early break\n            # there is nothing to flush for -- the window is already full.\n            for resampled in resampler.resample(None):\n                chunks.append(resampled.to_ndarray().reshape(-1, H3_AUDIO_CHANNELS))\n    if not chunks:\n        raise ValueError(f\"{Path(path).name} decoded to no audio samples.\")\n    samples = np.concatenate(chunks, axis = 0).astype(\"float32\")[:target_samples]\n    if samples.shape[0] < target_samples:\n        missing = target_samples - samples.shape[0]\n        if missing > _MAX_AUDIO_PAD_FRACTION * target_samples:\n            have_s = samples.shape[0] / H3_AUDIO_SAMPLING_RATE\n            want_s = target_samples / H3_AUDIO_SAMPLING_RATE\n            raise ValueError(\n                f\"{Path(path).name} carries {have_s:.2f}s of audio for a {want_s:.2f}s clip. \"\n                f\"MiniMax-H3 denoises video and audio together, so padding the rest with \"\n                f\"silence would train the adapter to stop generating sound. Use a clip whose \"\n                f\"soundtrack runs its full length.\"\n            )\n        samples = np.pad(samples, ((0, missing), (0, 0)))\n    # A muted track runs the clip's full length, so every check above passes and the window comes\n    # back all zeros -- the same target the short-audio refusal exists to keep out, arriving by a\n    # route that refusal cannot see. Measured as peak amplitude rather than mean energy so a clip\n    # that is merely quiet, or silent for most of its length with one real sound in it, is kept:\n    # only a track with nothing above the floor anywhere is turned away.\n    if float(np.max(np.abs(samples))) <= _SILENT_AUDIO_PEAK:\n        raise ValueError(\n            f\"{Path(path).name} has a soundtrack that is silent all the way through. \"\n            f\"MiniMax-H3 denoises video and audio together, so training on it would teach the \"\n            f\"adapter to stop generating sound. Use a clip whose soundtrack has audio in it, or \"\n            f\"take this one out of the dataset.\"\n        )","sourceCodeStart":445,"sourceCodeEnd":481,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/core/training/diffusion_h3_clips.py#L445-L481","documentation":"Raised by _decode_clip_audio() when the clip's audio runs short of the required sample count by more than _MAX_AUDIO_PAD_FRACTION of the window. Small shortfalls are padded with silence, but a large one is refused: MiniMax-H3 denoises video and audio together, so padding most of the window with silence would train the adapter to stop generating sound. Note the follow-up check separately rejects an all-zero (muted) track by peak amplitude.","triggerScenarios":"A video track longer than its audio track — audio starts late or ends early (e.g. 6s of video over 3s of audio); clips trimmed on the video stream only; sources whose soundtrack is shorter than the container duration.","commonSituations":"Editing software exporting video with detached/stopped audio; concatenations where the audio stream is shorter than the video stream; clips recorded with audio starting mid-recording; downloaded streams where the last audio packets are missing.","solutions":["Use a clip whose soundtrack runs the full length — remux/trim so audio covers the video (ffmpeg -i in.mp4 -t <aud_dur> -c copy out.mp4).","Trim the video to the audio's duration so the training window is fully covered.","Pre-scan dataset files comparing stream durations and flag any where audio_duration < video_duration beyond the pad tolerance."],"exampleFix":"# before\n# clip: 6.0s video, 3.0s audio, window 5.83s -> >pad fraction -> ValueError\n\n# after\n# trim video to the audio's length before adding to the dataset:\n#   ffmpeg -i clip.mp4 -t 3.0 -c copy trimmed.mp4","handlingStrategy":"validation","validationCode":"import av\n\ndef audio_covers_video(path: str, tolerance: float = 0.9) -> bool:\n    with av.open(path) as c:\n        v, a = c.streams.video[0], c.streams.audio[0]\n        vd = float(v.duration * v.time_base) if v.duration and v.time_base else 0.0\n        ad = float(a.duration * a.time_base) if a.duration and a.time_base else 0.0\n    if vd == 0.0 or ad == 0.0:\n        return True  # unknown -> let decode decide\n    return ad >= vd * tolerance","typeGuard":null,"tryCatchPattern":"try:\n    frames, waveform = decode_clip(p, num_frames=n, width=w, height=h)\nexcept ValueError as e:\n    if \"soundtrack runs its full length\" in str(e):\n        skip_and_log(p)  # or trim: ffmpeg -i p -t <audio_dur> -c copy trimmed.mp4\n    else:\n        raise","preventionTips":["Trim clips so the audio stream spans the whole video before ingest.","Compare audio vs video stream durations during dataset validation and flag short soundtracks."],"tags":["audio","video","dataset","minimax-h3"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}