Compare commits
3 Commits
8145be4108
...
d815b59def
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d815b59def | ||
|
|
a6dea1529a | ||
|
|
5ee371f0ae |
27
README.md
27
README.md
@@ -497,8 +497,8 @@ python streaming_turn_model.py \
|
||||
--start 0 --end 4 \
|
||||
--video-fps 2 \
|
||||
--strict-fixed-video-grid \
|
||||
--verify-every 5 \
|
||||
--verify-continuous-every 5 \
|
||||
--verify-every 1 \
|
||||
--verify-continuous-every 1 \
|
||||
--flash-attention-2 \
|
||||
--output features/Session_1_open_first_4s.pt
|
||||
```
|
||||
@@ -554,10 +554,12 @@ The sidecar selects the matching fixed-FPS MP4 and sets `N` to its exact
|
||||
`--strict-fixed-video-grid` is enabled.
|
||||
|
||||
In strict A+V mode the extractor does not delegate temporal frame selection to
|
||||
the generic video utility. It reads the already-fixed MP4 grid explicitly,
|
||||
uses only frames with timestamps `<= t`, and duplicates the most recent past
|
||||
frame when the visual tower needs an even frame count. Audio is loaded once at
|
||||
16 kHz and sliced exactly at each causal boundary. The processor still receives
|
||||
the generic video utility. It reads the already-fixed MP4 grid explicitly and
|
||||
assigns both video frames and audio samples with half-open intervals
|
||||
`[start, end)`. Thus a frame exactly on a two-second boundary belongs only to
|
||||
the following block. It duplicates the most recent available frame when the
|
||||
visual tower needs an even frame count. Audio is loaded once at 16 kHz and
|
||||
sliced at the same causal boundary. The processor still receives
|
||||
`use_audio_in_video=True`, so Qwen's audio/video token interleaving is retained.
|
||||
Long runs use `tqdm` and update the progress bar after every completed state,
|
||||
showing percentage, media time, elapsed time, ETA, and throughput. Pass
|
||||
@@ -576,15 +578,17 @@ python streaming_turn_model.py \
|
||||
--start 0 --end 4 \
|
||||
--video-fps 2 \
|
||||
--strict-fixed-video-grid \
|
||||
--verify-every 5 \
|
||||
--verify-continuous-every 5 \
|
||||
--verify-every 1 \
|
||||
--verify-continuous-every 1 \
|
||||
--flash-attention-2 \
|
||||
--output features/Session_1_first_4s_check.pt
|
||||
```
|
||||
|
||||
Do not launch all sessions unless `cache_replay` cosine is nearly 1. The
|
||||
`continuous_window_semantics` cosine answers a different question and may be
|
||||
lower because blockwise media preprocessing changes the representation.
|
||||
Do not launch all sessions unless `cache_replay` cosine is nearly 1. For
|
||||
`open-stream-replay`, a materially lower `continuous_window_semantics` cosine
|
||||
means that the custom payload stitching is not equivalent to one continuous
|
||||
Qwen input; it must not be dismissed as a media-turn-boundary effect because
|
||||
this mode intentionally keeps a single media turn open.
|
||||
|
||||
Video can be sampled at 2 FPS while predictions remain at 5 Hz. Audio and the
|
||||
causal boundary update every 200 ms; consecutive prediction times may use the
|
||||
@@ -667,6 +671,7 @@ Each `.pt` file contains:
|
||||
- `config`: step, native block, memory, FPS, and pixel settings;
|
||||
- `verification`: cached-versus-exact numerical checks;
|
||||
- `input_video_fps` and `video_sampling_grid`: sampling provenance;
|
||||
- `media_interval_policy`: fixed-grid AV uses half-open `[start, end)` ownership;
|
||||
- `logits`: optional `[N, 10, 3]` output if a trained head is supplied;
|
||||
- `probabilities`: optional softmax probabilities.
|
||||
|
||||
|
||||
@@ -243,7 +243,13 @@ class FixedGridAV:
|
||||
raise RuntimeError(f"Decoded audio is empty: {self.path}")
|
||||
|
||||
def frames(self, start: float, end: float) -> list[Any]:
|
||||
"""Return fixed-grid frames whose timestamps lie in [start, end)."""
|
||||
"""Return fixed-grid frames whose timestamps lie in ``[start, end)``.
|
||||
|
||||
Half-open ownership is essential at native block boundaries. For
|
||||
example, the frame at exactly 2.0 s belongs to ``[2.0, 4.0)`` and must
|
||||
not also be committed in ``[0.0, 2.0)``. Audio slicing below follows
|
||||
the same convention.
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
from PIL import Image
|
||||
@@ -1112,11 +1118,32 @@ class OpenStreamReplayExtractor:
|
||||
manual_audios=manual_audios,
|
||||
video_fps=self.config.video_fps,
|
||||
)
|
||||
return _open_media_pieces(
|
||||
pieces = _open_media_pieces(
|
||||
self.model,
|
||||
inputs,
|
||||
use_audio_in_video=use_audio_in_video,
|
||||
)
|
||||
# A standalone tail is at most one native 2 s block. Its temporal
|
||||
# TMRoPE coordinates must therefore stay inside one 50-position chunk.
|
||||
# This catches endpoint-inclusive frame selection (or another
|
||||
# preprocessing regression) before overlapping coordinates are
|
||||
# committed to the next block.
|
||||
duration = interval[1] - interval[0]
|
||||
if duration <= self.config.native_block_seconds + 1e-6:
|
||||
temporal_positions = pieces.payload_position_ids[0]
|
||||
temporal_span = int(
|
||||
temporal_positions.max().item()
|
||||
- temporal_positions.min().item()
|
||||
)
|
||||
positions_per_chunk = _tmrope_positions_per_chunk(self.model)
|
||||
if temporal_span >= positions_per_chunk:
|
||||
raise RuntimeError(
|
||||
"One open-stream AV interval spans multiple native TMRoPE "
|
||||
f"chunks: interval={interval}, temporal_span={temporal_span}, "
|
||||
f"chunk_size={positions_per_chunk}. Check frame-boundary "
|
||||
"ownership and audio preprocessing."
|
||||
)
|
||||
return pieces
|
||||
|
||||
def state_from_scratch(
|
||||
self,
|
||||
@@ -1701,6 +1728,11 @@ def main() -> None:
|
||||
if fixed_grid_av is not None
|
||||
else "qwen_utility_adaptive_sampling"
|
||||
),
|
||||
"media_interval_policy": (
|
||||
"half_open_[start,end)"
|
||||
if fixed_grid_av is not None
|
||||
else "qwen_utility_defined"
|
||||
),
|
||||
"open_stream_policy": (
|
||||
{
|
||||
"commit": "completed_2s_av_payload_only",
|
||||
|
||||
Reference in New Issue
Block a user