Files
hao-ai-lab-FastVideo/apps/dreamverse/gpu-pool.drawio

577 lines
56 KiB
Plaintext

<mxfile host="65bd71144e">
<diagram id="gpu-pool" name="gpu_pool.py">
<mxGraphModel dx="1687" dy="3380" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1300" pageHeight="1700" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="title" value="gpu_pool.py — runtime architecture" style="text;html=1;align=center;fontSize=18;fontStyle=1;" parent="1" vertex="1">
<mxGeometry x="350" y="-150" width="600" height="30" as="geometry"/>
</mxCell>
<mxCell id="client" value="Client (WebSocket)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=13;fontStyle=1;" parent="1" vertex="1">
<mxGeometry x="560" y="-60" width="180" height="60" as="geometry"/>
</mxCell>
<mxCell id="pool" value="GPUPool" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=13;fontStyle=1;" parent="1" vertex="1">
<mxGeometry x="560" y="60" width="180" height="60" as="geometry"/>
</mxCell>
<mxCell id="slot_wrap" value="GPUSlot (one per GPU)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#e6f2e0;strokeColor=#82b366;strokeWidth=2;verticalAlign=top;align=left;spacingLeft=15;spacingTop=8;fontSize=13;fontStyle=1;" parent="1" vertex="1">
<mxGeometry x="40" y="216" width="1220" height="455" as="geometry"/>
</mxCell>
<mxCell id="m_start" value="start()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10;align=left;spacingLeft=8;spacingTop=4;" parent="1" vertex="1">
<mxGeometry x="110" y="270" width="60" height="30" as="geometry"/>
</mxCell>
<mxCell id="m_shutdown" value="shutdown()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10;align=left;spacingLeft=8;spacingTop=4;" parent="1" vertex="1">
<mxGeometry x="180" y="270" width="70" height="30" as="geometry"/>
</mxCell>
<mxCell id="m_join" value="join_user()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10;align=left;spacingLeft=8;spacingTop=4;" parent="1" vertex="1">
<mxGeometry x="499" y="260" width="70" height="40" as="geometry"/>
</mxCell>
<mxCell id="m_step" value="user_step()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10;align=left;spacingLeft=8;spacingTop=4;" parent="1" vertex="1">
<mxGeometry x="580" y="260" width="80" height="40" as="geometry"/>
</mxCell>
<mxCell id="m_leave" value="leave_user()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10;align=left;spacingLeft=8;spacingTop=4;" parent="1" vertex="1">
<mxGeometry x="670" y="255" width="80" height="45" as="geometry"/>
</mxCell>
<mxCell id="m_send" value="_send_command()&lt;br&gt;&lt;br&gt;puts on command_queue,&lt;br&gt;blocks on response_queue.get&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;**for user agonistic commands&lt;/b&gt;&lt;/div&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10;align=left;spacingLeft=8;spacingTop=4;fontStyle=2;" parent="1" vertex="1">
<mxGeometry x="79" y="370" width="230" height="80" as="geometry"/>
</mxCell>
<mxCell id="m_send_tagged" value="_send_command_tagged()&lt;br&gt;&lt;br&gt;creates Future; registers in&lt;br&gt;_pending_futures[user_id];&lt;br&gt;ensures response reader; &lt;b&gt;awaits future&lt;/b&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;**for user specific commands&lt;/b&gt;&lt;/div&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10;align=left;spacingLeft=8;spacingTop=4;fontStyle=2;" parent="1" vertex="1">
<mxGeometry x="350" y="374" width="300" height="90" as="geometry"/>
</mxCell>
<mxCell id="m_reader" value="_response_reader()&lt;br&gt;&lt;br&gt;a while loop that reads response_queue;&lt;br&gt;dispatch WorkerEvent:&lt;br&gt;• media → _stream_queues&lt;br&gt;• acks/errors → _pending_futures" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=10;align=left;spacingLeft=8;spacingTop=4;fontStyle=2;" parent="1" vertex="1">
<mxGeometry x="800" y="360" width="340" height="110" as="geometry"/>
</mxCell>
<mxCell id="c_futures" value="«dict» _pending_futures&#xa;&#xa;{user_id → asyncio.Future}&#xa;&#xa;created by _send_command_tagged;&#xa;resolved + popped by _response_reader;&#xa;cleared on model reload or leave" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=10;align=left;spacingLeft=8;spacingTop=4;" parent="1" vertex="1">
<mxGeometry x="300" y="524" width="340" height="110" as="geometry"/>
</mxCell>
<mxCell id="c_streams" value="«dict» _stream_queues:&amp;nbsp;&lt;div&gt;&lt;span style=&quot;color: rgb(63, 63, 63); background-color: transparent;&quot;&gt;each is a queue of metadata that tell the consumer which part of the shared&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;font color=&quot;#000000&quot;&gt;stream buffer to read next.&lt;br&gt;&lt;/font&gt;&lt;br&gt;{user_id → asyncio.Queue}&lt;br&gt;&lt;br&gt;created by register_stream_queue()&lt;br&gt;written by _response_reader (MediaInit / Chunk / Complete);&lt;br&gt;consumed by&amp;nbsp; AV loop → ws.send_bytes / send_json;&lt;br&gt;popped by leave_user(); cleared on reload&lt;/div&gt;&lt;/div&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=10;align=left;spacingLeft=8;spacingTop=4;" parent="1" vertex="1">
<mxGeometry x="720" y="524" width="460" height="126" as="geometry"/>
</mxCell>
<mxCell id="div_line" value="" style="line;strokeColor=#888888;strokeWidth=1;dashed=1;" parent="1" vertex="1">
<mxGeometry x="40" y="690" width="1220" height="10" as="geometry"/>
</mxCell>
<mxCell id="div_label" value="── process boundary (mp.Queue + mp.RawArray) ──" style="text;html=1;align=center;fontSize=11;fontColor=#666666;fontStyle=2;" parent="1" vertex="1">
<mxGeometry x="450" y="688" width="400" height="20" as="geometry"/>
</mxCell>
<mxCell id="cmdq" value="command_queue" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;fillColor=#f8cecc;strokeColor=#b85450;fontSize=12;fontStyle=1;" parent="1" vertex="1">
<mxGeometry x="79" y="720" width="200" height="100" as="geometry"/>
</mxCell>
<mxCell id="respq" value="response_queue" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;fillColor=#f8cecc;strokeColor=#b85450;fontSize=12;fontStyle=1;" parent="1" vertex="1">
<mxGeometry x="520" y="720" width="200" height="100" as="geometry"/>
</mxCell>
<mxCell id="sharedbuf" value="shared_stream_buffer&#xa;(mp.RawArray, 256 MiB)&#xa;&#xa;zero-copy mp4 bytes" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;fillColor=#f8cecc;strokeColor=#b85450;fontSize=11;" parent="1" vertex="1">
<mxGeometry x="900" y="720" width="280" height="100" as="geometry"/>
</mxCell>
<mxCell id="worker_ipc" value="worker_ipc.py — shared types (imported on both sides of the process boundary)&#xa;&#xa;Command(type: CommandType, payload: CommandPayload | None, user_id: str | None)&#xa;CommandPayload = UserStepPayload | WarmupPayload | ReloadModelPayload&#xa;WorkerEvent = StepComplete | WorkerError | JoinAck | LeaveAck | ReloadAck | WarmupComplete | MediaInit | MediaChunk | MediaComplete | InitAck | ShutdownAck" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e0e0e0;strokeColor=#666666;fontSize=10;align=left;spacingLeft=10;spacingTop=6;fontFamily=monospace;fontStyle=1;" parent="1" vertex="1">
<mxGeometry x="80" y="860" width="1140" height="80" as="geometry"/>
</mxCell>
<mxCell id="worker_wrap" value="Worker Subprocess - in each GPUSlot" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#fef1e0;strokeColor=#d79b00;strokeWidth=2;verticalAlign=top;align=left;spacingLeft=15;spacingTop=8;fontSize=13;fontStyle=1;" parent="1" vertex="1">
<mxGeometry x="73" y="1071" width="1140" height="360" as="geometry"/>
</mxCell>
<mxCell id="dispatcher" value="command dispatcher&#xa;&#xa;gpu_worker_process() branches on&#xa;CommandType; asserts payload type&#xa;&#xa;INIT / WARMUP / RELOAD_MODEL&#xa;USER_JOIN / USER_STEP / USER_LEAVE&#xa;SHUTDOWN" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;fontSize=11;align=left;spacingLeft=10;spacingTop=8;fontStyle=1;" parent="1" vertex="1">
<mxGeometry x="120" y="1120" width="240" height="120" as="geometry"/>
</mxCell>
<mxCell id="do_step" value="VideoGenerationWorker.generate_step()&#xa;video_generation.py:380&#xa;&#xa;reads + updates ContinuationState,&#xa;calls generator" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;fontSize=11;align=left;spacingLeft=10;spacingTop=8;fontStyle=1;" parent="1" vertex="1">
<mxGeometry x="460" y="1120" width="240" height="120" as="geometry"/>
</mxCell>
<mxCell id="stream_av" value="stream_fmp4()&#xa;av_streaming.py:121&#xa;&#xa;trims overlap, pipes to ffmpeg,&#xa;publishes StreamInit / StreamChunk /&#xa;StreamComplete via callback" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#b1d8d7;strokeColor=#23445d;fontSize=11;align=left;spacingLeft=10;spacingTop=8;fontStyle=1;" parent="1" vertex="1">
<mxGeometry x="800" y="1120" width="260" height="120" as="geometry"/>
</mxCell>
<mxCell id="Ot8BU52QTIb4EhyRSe7I-2" value="" style="edgeStyle=none;html=1;" parent="1" source="generator" target="Ot8BU52QTIb4EhyRSe7I-1" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="generator" value="VideoGenerator (fastvideo)&#xa;&#xa;LTX2 DiT + refine upsampler&#xa;FP4 quant, torch.compile&#xa;&#xa;owned by VideoGenerationWorker&#xa;video_generation.py:211" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;fontSize=11;" parent="1" vertex="1">
<mxGeometry x="460" y="1300" width="240" height="100" as="geometry"/>
</mxCell>
<mxCell id="ffmpeg" value="ffmpeg subprocess&#xa;&#xa;libx264 / *_nvenc&#xa;fragmented mp4" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#d79b00;fontSize=11;" parent="1" vertex="1">
<mxGeometry x="800" y="1300" width="260" height="100" as="geometry"/>
</mxCell>
<mxCell id="caches" value="ContinuationState&#xa;video_generation.py:89&#xa;&#xa;• video_images: list[PIL.Image]&#xa;• audio_latents: torch.Tensor (CPU)&#xa;&#xa;carried across segments" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;fontSize=11;align=left;spacingLeft=10;spacingTop=8;" parent="1" vertex="1">
<mxGeometry x="120" y="1300" width="240" height="100" as="geometry"/>
</mxCell>
<mxCell id="e_cp" value="acquire" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#6c8ebf;endArrow=classic;fontSize=11;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="client" target="pool" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="e_ps" value="assigns slot" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#82b366;endArrow=classic;fontSize=11;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="pool" target="slot_wrap" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="e_start_send" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#82b366;endArrow=classic;fontSize=10;" parent="1" target="m_send" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="138" y="300" as="sourcePoint"/>
<Array as="points">
<mxPoint x="138" y="380"/>
<mxPoint x="138" y="380"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="e_join_tag" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#82b366;endArrow=classic;fontSize=10;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="m_join" target="m_send_tagged" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="531.6999999999998" y="400.3600000000001" as="targetPoint"/>
<Array as="points">
<mxPoint x="532" y="300"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="e_step_tag" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#82b366;endArrow=classic;fontSize=10;exitX=0.1;exitY=1;exitDx=0;exitDy=0;" parent="1" source="m_step" target="m_send_tagged" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="588" y="400" as="targetPoint"/>
<Array as="points">
<mxPoint x="588" y="337"/>
<mxPoint x="590" y="337"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="e_leave_tag" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#82b366;endArrow=classic;fontSize=10;exitX=0.1;exitY=1;exitDx=0;exitDy=0;entryX=0.874;entryY=-0.002;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" source="m_leave" target="m_send_tagged" edge="1">
<mxGeometry x="-0.1388" relative="1" as="geometry">
<Array as="points">
<mxPoint x="680" y="300"/>
<mxPoint x="680" y="330"/>
<mxPoint x="612" y="330"/>
</Array>
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_tag_futures" value="register future" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#d6b656;endArrow=classic;fontSize=10;exitX=0.397;exitY=0.989;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitPerimeter=0;" parent="1" source="m_send_tagged" target="c_futures" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="e_reader_futures" value="&lt;b&gt;set future result&lt;/b&gt;" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#d6b656;endArrow=classic;fontSize=10;exitX=0.008;exitY=0.908;exitDx=0;exitDy=0;entryX=1;entryY=0.3;entryDx=0;entryDy=0;exitPerimeter=0;" parent="1" source="m_reader" target="c_futures" edge="1">
<mxGeometry x="-0.325" relative="1" as="geometry">
<Array as="points">
<mxPoint x="803" y="470"/>
<mxPoint x="670" y="470"/>
<mxPoint x="670" y="557"/>
</Array>
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_reader_streams" value="put(MediaEvent)" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#d6b656;endArrow=classic;fontSize=10;exitX=0.146;exitY=1.008;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.282;entryY=0.021;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" source="m_reader" target="c_streams" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points"/>
<mxPoint x="850" y="522" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="e_send_cmdq" value="put Command" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#b85450;endArrow=classic;fontSize=11;entryX=0.35;entryY=0;entryDx=0;entryDy=0;" parent="1" source="m_send" target="cmdq" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="150" y="585"/>
<mxPoint x="149" y="585"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="e_tag_cmdq" value="put Command" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#b85450;endArrow=classic;fontSize=11;exitX=0.022;exitY=0.97;exitDx=0;exitDy=0;entryX=0.85;entryY=0;entryDx=0;entryDy=0;exitPerimeter=0;" parent="1" source="m_send_tagged" target="cmdq" edge="1">
<mxGeometry x="0.1755" relative="1" as="geometry">
<Array as="points">
<mxPoint x="357" y="490"/>
<mxPoint x="250" y="490"/>
<mxPoint x="250" y="592"/>
<mxPoint x="249" y="592"/>
</Array>
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_respq_reader" value="WorkerEvent" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#b85450;endArrow=classic;fontSize=11;exitX=0.753;exitY=0.056;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitPerimeter=0;" parent="1" source="respq" target="m_reader" edge="1">
<mxGeometry x="0.7113" relative="1" as="geometry">
<Array as="points">
<mxPoint x="671" y="720"/>
<mxPoint x="670" y="720"/>
<mxPoint x="670" y="415"/>
</Array>
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_respq_send" value="blocking .get" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#b85450;endArrow=classic;dashed=1;fontSize=10;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="respq" target="m_send" edge="1">
<mxGeometry x="-0.2187" relative="1" as="geometry">
<Array as="points">
<mxPoint x="520" y="680"/>
<mxPoint x="200" y="680"/>
</Array>
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_cd" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#b85450;endArrow=classic;fontSize=11;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.25;entryY=0;entryDx=0;entryDy=0;" parent="1" source="cmdq" edge="1" target="dispatcher">
<mxGeometry relative="1" as="geometry">
<mxPoint x="310" y="1120" as="targetPoint"/>
<Array as="points">
<mxPoint x="179" y="970"/>
<mxPoint x="180" y="970"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="e_dds" value="USER_STEP" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#d79b00;endArrow=classic;fontSize=10;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="dispatcher" target="do_step" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="e_dr" value="StepComplete / ack types" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#b85450;endArrow=classic;fontSize=10;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.15;entryY=1;entryDx=0;entryDy=0;" parent="1" source="dispatcher" target="respq" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="240" y="1000"/>
<mxPoint x="550" y="1000"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="e_dsg" value="generator.generate_video()" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#9673a6;endArrow=classic;fontSize=10;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="do_step" target="generator" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="e_dscache" value="read / write" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#d6b656;endArrow=classic;startArrow=classic;fontSize=10;exitX=0;exitY=0.8;exitDx=0;exitDy=0;entryX=1;entryY=0.2;entryDx=0;entryDy=0;" parent="1" source="do_step" target="caches" edge="1">
<mxGeometry relative="1" as="geometry"/>
<Array as="points">
<mxPoint x="420" y="1058"/>
<mxPoint x="420" y="1150"/>
</Array>
</mxCell>
<mxCell id="e_dsstream" value="frames + audio" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#d79b00;endArrow=classic;fontSize=10;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="do_step" target="stream_av" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="e_sf" value="rawvideo + wav" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#d79b00;endArrow=classic;fontSize=10;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="stream_av" target="ffmpeg" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="e_ssb" value="write mp4 bytes&#xa;at shared_write_offset" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#b85450;endArrow=classic;fontSize=10;exitX=0.75;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="1" source="stream_av" target="sharedbuf" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="e_sbs" value="bytes from the buffer are sent through websocket&amp;nbsp;&lt;div&gt;based on info from the stream queue&lt;/div&gt;" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#b85450;endArrow=classic;dashed=1;fontSize=10;exitX=0.591;exitY=0.027;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;exitPerimeter=0;" parent="1" source="sharedbuf" target="c_streams" edge="1">
<mxGeometry x="0.0048" relative="1" as="geometry">
<Array as="points">
<mxPoint x="1066" y="720"/>
</Array>
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="e_scl" value="session AV loop (main.py:2124):&#xa;ws.send_bytes(chunk) — binary mp4 frames&#xa;ws.send_json({type: media_init | media_segment_complete | ...})" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#6c8ebf;endArrow=classic;fontSize=10;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="c_streams" target="client" edge="1">
<mxGeometry x="0.0003" relative="1" as="geometry">
<mxPoint as="offset"/>
<Array as="points">
<mxPoint x="1310" y="577"/>
<mxPoint x="1310" y="-30"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="e_sr" value="MediaChunk (offset, len)" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#b85450;endArrow=classic;fontSize=10;exitX=0.1;exitY=0;exitDx=0;exitDy=0;entryX=0.85;entryY=1;entryDx=0;entryDy=0;" parent="1" source="stream_av" target="respq" edge="1">
<mxGeometry relative="1" as="geometry"/>
<Array as="points">
<mxPoint x="826" y="880"/>
<mxPoint x="690" y="880"/>
</Array>
</mxCell>
<mxCell id="legend" value="Legend&#xa;&#xa;■ blue client / external&#xa;■ green main-process pool/slot&#xa; (methods — italic label)&#xa;■ yellow containers (routing state)&#xa;■ red IPC primitives (mp.Queue, mp.RawArray)&#xa;&#xa;Worker subprocess modules:&#xa;■ orange gpu_pool.py (dispatcher)&#xa;■ lavender video_generation.py&#xa;■ teal av_streaming.py&#xa;■ gray worker_ipc.py (shared types)&#xa;&#xa;Flow:&#xa; client → pool → slot&#xa; → _send_command(_tagged) → command_queue&#xa; → dispatcher → generate_step()&#xa; → stream_fmp4() → ffmpeg&#xa; → shared_buf + response_queue&#xa; → _response_reader → futures / stream_queues&#xa; → client awaits (via main.py AV loop)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#999999;fontSize=11;align=left;spacingLeft=10;spacingTop=8;" parent="1" vertex="1">
<mxGeometry x="39" y="-200" width="270" height="380" as="geometry"/>
</mxCell>
<mxCell id="Ot8BU52QTIb4EhyRSe7I-1" value="FastVideo video_generator" style="whiteSpace=wrap;html=1;fontSize=11;fillColor=#e1d5e7;strokeColor=#9673a6;rounded=1;" parent="1" vertex="1">
<mxGeometry x="520" y="1470" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="5" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#82b366;endArrow=classic;fontSize=10;exitX=0.421;exitY=1.01;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.569;entryY=0.02;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="m_shutdown" target="m_send">
<mxGeometry relative="1" as="geometry">
<mxPoint x="260" y="300" as="sourcePoint"/>
<mxPoint x="260" y="400" as="targetPoint"/>
<Array as="points"/>
</mxGeometry>
</mxCell>
<mxCell id="6" style="edgeStyle=orthogonalEdgeStyle;html=1;entryX=0.983;entryY=0.021;entryDx=0;entryDy=0;entryPerimeter=0;strokeColor=#61A25D;" edge="1" parent="1" source="m_join" target="m_send">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="534" y="320"/>
<mxPoint x="306" y="320"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="11" value="reload model" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="6">
<mxGeometry x="0.1965" relative="1" as="geometry">
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="9" value="" style="group" vertex="1" connectable="0" parent="1">
<mxGeometry x="1340" y="750" width="240" height="40" as="geometry"/>
</mxCell>
<mxCell id="7" value="" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=6.353056066176691;fillColor=#f8cecc;strokeColor=#b85450;fontSize=11;" vertex="1" parent="9">
<mxGeometry y="4" width="21.39" height="22" as="geometry"/>
</mxCell>
<mxCell id="8" value="Queue: owned by GPUSlot, passed to worker process as argument." style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="9">
<mxGeometry x="21.3900000000001" width="218.61" height="40" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>
</diagram>
<diagram id="gpu-pool-boot" name="boot &amp; ws">
<mxGraphModel grid="1" page="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" pageScale="1" pageWidth="1300" pageHeight="1900" math="0" shadow="0">
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="b_title" value="gpu_pool.py — boot flow &amp; websocket session" style="text;html=1;align=center;fontSize=18;fontStyle=1;" parent="1" vertex="1">
<mxGeometry x="350" y="20" width="600" height="30" as="geometry"/>
</mxCell>
<mxCell id="secA" value="A. Call chain" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#e1f5fe;strokeColor=#039be5;strokeWidth=2;verticalAlign=top;align=left;spacingLeft=15;spacingTop=8;fontSize=13;fontStyle=1;" parent="1" vertex="1">
<mxGeometry x="40" y="70" width="400" height="420" as="geometry"/>
</mxCell>
<mxCell id="a1" value="$ uv run dreamverse-server" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#039be5;fontSize=12;fontFamily=monospace;" parent="1" vertex="1">
<mxGeometry x="70" y="120" width="340" height="40" as="geometry"/>
</mxCell>
<mxCell id="a2" value="server_entry.cli()&#xa;(pyproject.toml [project.scripts])&#xa;&#xa;guards missing fastvideo extra" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#039be5;fontSize=11;align=left;spacingLeft=10;" parent="1" vertex="1">
<mxGeometry x="70" y="180" width="340" height="70" as="geometry"/>
</mxCell>
<mxCell id="a3" value="main.cli() (main.py:2325)&#xa;&#xa;argparse --host/--port&#xa;uvicorn.run(app, host, port)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#039be5;fontSize=11;align=left;spacingLeft=10;" parent="1" vertex="1">
<mxGeometry x="70" y="270" width="340" height="80" as="geometry"/>
</mxCell>
<mxCell id="a4" value="FastAPI(lifespan=lifespan)&#xa;(main.py:147)&#xa;&#xa;on startup → enter lifespan ctx → Section B" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#039be5;fontSize=11;align=left;spacingLeft=10;" parent="1" vertex="1">
<mxGeometry x="70" y="370" width="340" height="90" as="geometry"/>
</mxCell>
<mxCell id="ea12" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#039be5;endArrow=classic;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="a1" target="a2" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="ea23" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#039be5;endArrow=classic;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="a2" target="a3" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="ea34" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#039be5;endArrow=classic;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="a3" target="a4" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="secB" value="B. lifespan() zoom (main.py:116-144)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#f3e5f5;strokeColor=#8e24aa;strokeWidth=2;verticalAlign=top;align=left;spacingLeft=15;spacingTop=8;fontSize=13;fontStyle=1;" parent="1" vertex="1">
<mxGeometry x="480" y="70" width="780" height="420" as="geometry"/>
</mxCell>
<mxCell id="b1" value="1. gpu_ids = get_available_gpus()&#xa; respects FASTVIDEO_GPU_COUNT env" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#8e24aa;fontSize=11;align=left;spacingLeft=10;fontFamily=monospace;" parent="1" vertex="1">
<mxGeometry x="510" y="115" width="720" height="45" as="geometry"/>
</mxCell>
<mxCell id="b2" value="2. gpu_pool = GPUPool(gpu_ids)&#xa; creates one GPUSlot per GPU (not yet started)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#8e24aa;fontSize=11;align=left;spacingLeft=10;fontFamily=monospace;" parent="1" vertex="1">
<mxGeometry x="510" y="170" width="720" height="45" as="geometry"/>
</mxCell>
<mxCell id="b3" value="3. await gpu_pool.initialize()&#xa; asyncio.create_task(_init_gpu(id)) for each GPU&#xa; returns immediately — GPUs init in background → Section C" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff9c4;strokeColor=#8e24aa;fontSize=11;align=left;spacingLeft=10;fontFamily=monospace;" parent="1" vertex="1">
<mxGeometry x="510" y="225" width="720" height="60" as="geometry"/>
</mxCell>
<mxCell id="b4" value="4. prompt_enhancer = PromptEnhancer()&#xa;5. session_event_logger = SessionEventLogger(...)&#xa;6. prompt_safety_filter = PromptSafetyFilter() (optional)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#8e24aa;fontSize=11;align=left;spacingLeft=10;fontFamily=monospace;" parent="1" vertex="1">
<mxGeometry x="510" y="295" width="720" height="55" as="geometry"/>
</mxCell>
<mxCell id="byield" value="yield&#xa;server is now accepting HTTP + WS&#xa;/healthz → 200 /readyz → 503 until GPUs warm up" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#c8e6c9;strokeColor=#388e3c;fontSize=11;align=left;spacingLeft=10;fontStyle=1;" parent="1" vertex="1">
<mxGeometry x="510" y="360" width="720" height="55" as="geometry"/>
</mxCell>
<mxCell id="bshut" value="[on shutdown] await gpu_pool.shutdown()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffcdd2;strokeColor=#c62828;fontSize=11;align=left;spacingLeft=10;fontFamily=monospace;" parent="1" vertex="1">
<mxGeometry x="510" y="425" width="720" height="35" as="geometry"/>
</mxCell>
<mxCell id="eab" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#666;endArrow=classic;dashed=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.2;entryDx=0;entryDy=0;" parent="1" source="a4" target="b1" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="secC" value="C. GPUSlot.start() zoom — runs in background per GPU (gpu_pool.py:426)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#fff3e0;strokeColor=#ef6c00;strokeWidth=2;verticalAlign=top;align=left;spacingLeft=15;spacingTop=8;fontSize=13;fontStyle=1;" parent="1" vertex="1">
<mxGeometry x="40" y="530" width="1220" height="520" as="geometry"/>
</mxCell>
<mxCell id="cparent" value="Parent (main) process" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#ffe0b2;strokeColor=#ef6c00;fontSize=12;fontStyle=1;verticalAlign=top;align=left;spacingLeft=10;spacingTop=5;" parent="1" vertex="1">
<mxGeometry x="70" y="580" width="380" height="440" as="geometry"/>
</mxCell>
<mxCell id="cp1" value="mp.get_context(&#39;spawn&#39;)&#xa;cmd_q, resp_q = ctx.Queue(), ctx.Queue()&#xa;(optional) shared_stream_buffer = mp.RawArray(&#39;B&#39;, 256 MiB)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#ef6c00;fontSize=10;align=left;spacingLeft=8;fontFamily=monospace;" parent="1" vertex="1">
<mxGeometry x="85" y="620" width="350" height="60" as="geometry"/>
</mxCell>
<mxCell id="cp2" value="ctx.Process(target=gpu_worker_process,&#xa; args=(gpu_id, cuda_device, cmd_q, resp_q, ...))&#xa;process.start()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#ef6c00;fontSize=10;align=left;spacingLeft=8;fontFamily=monospace;" parent="1" vertex="1">
<mxGeometry x="85" y="690" width="350" height="60" as="geometry"/>
</mxCell>
<mxCell id="cp3" value="_send_command(Command(INIT), timeout=600s)&#xa; await response on resp_q" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#ef6c00;fontSize=10;align=left;spacingLeft=8;fontFamily=monospace;" parent="1" vertex="1">
<mxGeometry x="85" y="760" width="350" height="50" as="geometry"/>
</mxCell>
<mxCell id="cp4" value="if STARTUP_WARMUP_ENABLED:&#xa; _send_command(Command(WARMUP, prompt=...),&#xa; timeout=STARTUP_WARMUP_TIMEOUT)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#ef6c00;fontSize=10;align=left;spacingLeft=8;fontFamily=monospace;" parent="1" vertex="1">
<mxGeometry x="85" y="820" width="350" height="60" as="geometry"/>
</mxCell>
<mxCell id="cp5" value="slot.ready = True" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#c8e6c9;strokeColor=#388e3c;fontSize=11;fontStyle=1;fontFamily=monospace;" parent="1" vertex="1">
<mxGeometry x="85" y="890" width="350" height="35" as="geometry"/>
</mxCell>
<mxCell id="cp6" value="parent now enters pool as a ready slot;&#xa;/readyz flips to 200 once ≥1 slot is ready" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#888;fontSize=10;align=left;spacingLeft=8;fontStyle=2;" parent="1" vertex="1">
<mxGeometry x="85" y="935" width="350" height="45" as="geometry"/>
</mxCell>
<mxCell id="cipc" value="IPC" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#ffcdd2;strokeColor=#b71c1c;fontSize=12;fontStyle=1;verticalAlign=top;align=center;spacingTop=5;" parent="1" vertex="1">
<mxGeometry x="480" y="580" width="150" height="440" as="geometry"/>
</mxCell>
<mxCell id="ccmdq" value="command_queue&#xa;(mp.Queue)" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;fillColor=#f8cecc;strokeColor=#b85450;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="490" y="650" width="130" height="80" as="geometry"/>
</mxCell>
<mxCell id="crespq" value="response_queue&#xa;(mp.Queue)" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;fillColor=#f8cecc;strokeColor=#b85450;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="490" y="760" width="130" height="80" as="geometry"/>
</mxCell>
<mxCell id="cshared" value="shared_stream_buffer&#xa;(mp.RawArray)" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;fillColor=#f8cecc;strokeColor=#b85450;fontSize=10;" parent="1" vertex="1">
<mxGeometry x="490" y="870" width="130" height="80" as="geometry"/>
</mxCell>
<mxCell id="cworker" value="Worker subprocess (gpu_worker_process, gpu_pool.py:151)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#fef1e0;strokeColor=#d79b00;fontSize=12;fontStyle=1;verticalAlign=top;align=left;spacingLeft=10;spacingTop=5;" parent="1" vertex="1">
<mxGeometry x="660" y="580" width="580" height="440" as="geometry"/>
</mxCell>
<mxCell id="cw1" value="os.environ[&#39;CUDA_VISIBLE_DEVICES&#39;] = cuda_device&#xa;os.environ[&#39;FASTVIDEO_ATTENTION_BACKEND&#39;] = &#39;FLASH_ATTN&#39;&#xa;&#xa;must be set BEFORE importing torch" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#d79b00;fontSize=10;align=left;spacingLeft=8;fontFamily=monospace;" parent="1" vertex="1">
<mxGeometry x="675" y="620" width="550" height="65" as="geometry"/>
</mxCell>
<mxCell id="cw2" value="from fastvideo.entrypoints.video_generator import VideoGenerator&#xa;from fastvideo.models.dits.ltx2 import DEFAULT_LTX2_AUDIO_*&#xa;&#xa;** Dreamverse reaches into fastvideo internals here **" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffe0b2;strokeColor=#d79b00;fontSize=10;align=left;spacingLeft=8;fontFamily=monospace;" parent="1" vertex="1">
<mxGeometry x="675" y="695" width="550" height="60" as="geometry"/>
</mxCell>
<mxCell id="cw3" value="on Command(INIT):&#xa; VideoGenerationWorker.initialize() (video_generation.py:247)&#xa; maybe_download_model(model_id)&#xa; VideoGenerator.from_pretrained(path, FP4Config, PipelineConfig)&#xa; load audio VAE, resolve refine upsampler&#xa; resp_q.put(InitAck(success=True))" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#d79b00;fontSize=10;align=left;spacingLeft=8;fontFamily=monospace;" parent="1" vertex="1">
<mxGeometry x="675" y="765" width="550" height="95" as="geometry"/>
</mxCell>
<mxCell id="cw4" value="on Command(WARMUP) with WarmupPayload:&#xa; VideoGenerationWorker.warmup(payload.prompt) (video_generation.py:518)&#xa; two synthetic segments prime caches + torch.compile&#xa; resp_q.put(WarmupComplete(timings=...))" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#d79b00;fontSize=10;align=left;spacingLeft=8;fontFamily=monospace;" parent="1" vertex="1">
<mxGeometry x="675" y="870" width="550" height="55" as="geometry"/>
</mxCell>
<mxCell id="cw5" value="enter main worker loop → waits for JOIN_USER / USER_STEP / LEAVE" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#c8e6c9;strokeColor=#388e3c;fontSize=11;fontStyle=1;fontFamily=monospace;" parent="1" vertex="1">
<mxGeometry x="675" y="935" width="550" height="40" as="geometry"/>
</mxCell>
<mxCell id="cea1" value="Command" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#b85450;endArrow=classic;fontSize=10;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="cp3" target="ccmdq" edge="1">
<mxGeometry relative="1" as="geometry"/>
</mxCell>
<mxCell id="cea2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#b85450;endArrow=classic;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="ccmdq" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="675" y="780" as="targetPoint"/>
<Array as="points">
<mxPoint x="648" y="690"/>
<mxPoint x="648" y="780"/>
<mxPoint x="675" y="780"/>
</Array>
</mxGeometry>
</mxCell>
<mxCell id="cea3" value="WorkerEvent" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#b85450;endArrow=classic;fontSize=10;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.969;entryY=0.798;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" target="crespq" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="684" y="825.5" as="sourcePoint"/>
<mxPoint x="629" y="813" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="cea4" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;strokeColor=#b85450;endArrow=classic;exitX=0;exitY=0.5;exitDx=0;exitDy=0;entryX=0.995;entryY=0.887;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" target="cp3" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="490" y="804" as="sourcePoint"/>
<mxPoint x="435" y="789" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="secD" value="D. WebSocket session — after startup" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#e8f5e9;strokeColor=#2e7d32;strokeWidth=2;verticalAlign=top;align=left;spacingLeft=15;spacingTop=8;fontSize=13;fontStyle=1;" parent="1" vertex="1">
<mxGeometry x="40" y="1080" width="1220" height="820" as="geometry"/>
</mxCell>
<mxCell id="dc_head" value="Browser / WS" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=11;fontStyle=1;" parent="1" vertex="1">
<mxGeometry x="80" y="1130" width="160" height="40" as="geometry"/>
</mxCell>
<mxCell id="ds_head" value="main.py / Session" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=11;fontStyle=1;" parent="1" vertex="1">
<mxGeometry x="290" y="1130" width="180" height="40" as="geometry"/>
</mxCell>
<mxCell id="dp_head" value="GPUPool" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=11;fontStyle=1;" parent="1" vertex="1">
<mxGeometry x="520" y="1130" width="160" height="40" as="geometry"/>
</mxCell>
<mxCell id="dsl_head" value="GPUSlot" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e6f2e0;strokeColor=#82b366;fontSize=11;fontStyle=1;" parent="1" vertex="1">
<mxGeometry x="730" y="1130" width="160" height="40" as="geometry"/>
</mxCell>
<mxCell id="dw_head" value="Worker subprocess" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fef1e0;strokeColor=#d79b00;fontSize=11;fontStyle=1;" parent="1" vertex="1">
<mxGeometry x="940" y="1130" width="200" height="40" as="geometry"/>
</mxCell>
<mxCell id="dc_life" style="endArrow=none;html=1;strokeColor=#6c8ebf;dashed=1;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="160" y="1175" as="sourcePoint"/>
<mxPoint x="160" y="1885" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="ds_life" style="endArrow=none;html=1;strokeColor=#82b366;dashed=1;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="380" y="1175" as="sourcePoint"/>
<mxPoint x="380" y="1885" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="dp_life" style="endArrow=none;html=1;strokeColor=#82b366;dashed=1;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="600" y="1175" as="sourcePoint"/>
<mxPoint x="600" y="1885" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="dsl_life" style="endArrow=none;html=1;strokeColor=#82b366;dashed=1;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="810" y="1175" as="sourcePoint"/>
<mxPoint x="810" y="1885" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="dw_life" style="endArrow=none;html=1;strokeColor=#d79b00;dashed=1;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="1040" y="1175" as="sourcePoint"/>
<mxPoint x="1040" y="1885" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="dm1" value="1. WS connect /ws + session_init_v2" style="endArrow=classic;html=1;strokeColor=#6c8ebf;fontSize=10;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="160" y="1200" as="sourcePoint"/>
<mxPoint x="380" y="1200" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="dm2" value="2. pool.acquire(client_id, ws)" style="endArrow=classic;html=1;strokeColor=#82b366;fontSize=10;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="380" y="1240" as="sourcePoint"/>
<mxPoint x="600" y="1240" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="dm3a" value="3a. if slot free: (gpu_id, slot)" style="endArrow=classic;html=1;strokeColor=#82b366;fontSize=10;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="600" y="1280" as="sourcePoint"/>
<mxPoint x="380" y="1280" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="dm3b" value="3b. else: enqueue, emit queue_status until a slot frees" style="endArrow=classic;html=1;strokeColor=#c62828;fontSize=10;dashed=1;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="600" y="1320" as="sourcePoint"/>
<mxPoint x="160" y="1320" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="dm4" value="4. emit gpu_assigned" style="endArrow=classic;html=1;strokeColor=#6c8ebf;fontSize=10;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="380" y="1360" as="sourcePoint"/>
<mxPoint x="160" y="1360" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="dm5" value="5. slot._send_command_tagged(Command(USER_JOIN))" style="endArrow=classic;html=1;strokeColor=#82b366;fontSize=10;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="380" y="1400" as="sourcePoint"/>
<mxPoint x="810" y="1400" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="dm6" value="6. command_queue.put(JOIN_USER)" style="endArrow=classic;html=1;strokeColor=#b85450;fontSize=10;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="810" y="1440" as="sourcePoint"/>
<mxPoint x="1040" y="1440" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="dssteady" value="── steady state: per prompt ──" style="text;html=1;align=center;fontSize=11;fontColor=#666;fontStyle=2;" parent="1" vertex="1">
<mxGeometry x="300" y="1470" width="600" height="25" as="geometry"/>
</mxCell>
<mxCell id="dm7" value="7. append_prompt / simple_generate" style="endArrow=classic;html=1;strokeColor=#6c8ebf;fontSize=10;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="160" y="1510" as="sourcePoint"/>
<mxPoint x="380" y="1510" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="dm9" value="8. slot._send_command_tagged(Command(USER_STEP, payload=UserStepPayload(prompt, segment_idx, image_path, reset_conditioning)))" style="endArrow=classic;html=1;strokeColor=#82b366;fontSize=10;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="380" y="1560" as="sourcePoint"/>
<mxPoint x="810" y="1560" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="dm10" value="9. command_queue.put(USER_STEP)" style="endArrow=classic;html=1;strokeColor=#b85450;fontSize=10;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="810" y="1610" as="sourcePoint"/>
<mxPoint x="1040" y="1610" as="targetPoint"/>
</mxGeometry>
</mxCell>
<mxCell id="dm11a" value="10a. worker runs:&#xa;VideoGenerationWorker.generate_step()&#xa; (video_generation.py:380)&#xa; → generator.generate_video()&#xa; → updates ContinuationState&#xa;then stream_fmp4() (av_streaming.py:121)&#xa; → ffmpeg (rawvideo+wav → fmp4)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffe0b2;strokeColor=#d79b00;fontSize=10;align=left;spacingLeft=8;fontFamily=monospace;" parent="1" vertex="1">
<mxGeometry x="955" y="1640" width="180" height="70" as="geometry"/>
</mxCell>
<mxCell id="dm11" value="10b. resp_q.put(MediaInit / MediaChunk / MediaComplete / StepComplete)" style="endArrow=classic;html=1;strokeColor=#b85450;fontSize=10;labelBackgroundColor=#ffffff;" parent="1" edge="1">
<mxGeometry x="0.0435" relative="1" as="geometry">
<mxPoint x="1092" y="1733" as="sourcePoint"/>
<mxPoint x="862" y="1733" as="targetPoint"/>
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="dm12" value="11. _response_reader isinstance-dispatches: MediaChunk/etc → _stream_queues[user_id]; StepComplete → _pending_futures" style="endArrow=classic;html=1;strokeColor=#d6b656;fontSize=10;" parent="1" edge="1">
<mxGeometry x="0.0014" relative="1" as="geometry">
<mxPoint x="810" y="1760" as="sourcePoint"/>
<mxPoint x="380" y="1760" as="targetPoint"/>
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="dm13a" value="12a. binary WS frame (mp4 bytes)" style="endArrow=classic;html=1;strokeColor=#6c8ebf;fontSize=10;labelBackgroundColor=#ffffff;" parent="1" edge="1">
<mxGeometry x="-0.0909" relative="1" as="geometry">
<mxPoint x="380" y="1795" as="sourcePoint"/>
<mxPoint x="160" y="1795" as="targetPoint"/>
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="dm13b" value="12b. JSON WS event (media_init, media_segment_complete, prompt_ready, …)" style="endArrow=classic;html=1;strokeColor=#6c8ebf;fontSize=10;labelBackgroundColor=#ffffff;" parent="1" edge="1">
<mxGeometry x="-0.0909" y="5" relative="1" as="geometry">
<mxPoint x="380" y="1825" as="sourcePoint"/>
<mxPoint x="160" y="1825" as="targetPoint"/>
<mxPoint as="offset"/>
</mxGeometry>
</mxCell>
<mxCell id="dm14" value="13. on WS close: pool.release(client_id) → Command(USER_LEAVE) → LeaveAck" style="endArrow=classic;html=1;strokeColor=#c62828;fontSize=10;dashed=1;labelBackgroundColor=#ffffff;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="160" y="1865" as="sourcePoint"/>
<mxPoint x="1040" y="1865" as="targetPoint"/>
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>