Compare commits

..
Author SHA1 Message Date
rlsu9 34a64597f4 update 2024-12-04 01:42:35 +04:00
rlsu9 4998121d6d update 2024-12-04 01:32:29 +04:00
rlsu9 1c25e3ed55 update 2024-12-04 01:24:30 +04:00
rlsu9 e98886f32f update 2024-12-03 10:03:26 +04:00
rlsu9 8619d2942d add l2 2024-12-03 09:53:44 +04:00
rlsu9 1876244531 update 2024-12-03 09:22:01 +04:00
rlsu9 34f709725e update 2024-12-03 01:44:07 +04:00
rlsu9 c5d6341f98 update 2024-12-02 22:45:29 +04:00
rlsu9 5325aa2cd2 xMerge branch 'main' of https://github.com/jzhang38/FastVideo-OSP into peiyuan 2024-12-02 22:31:48 +04:00
rlsu9 74d6fc92a9 update 2024-12-02 22:30:34 +04:00
haoanyscale daaefc5f63 fix finetune code bug 2024-12-02 11:45:04 +00:00
rlsu9 3eee42e917 update 2024-12-02 11:06:16 +04:00
rlsu9 28c0a5dce9 update 2024-12-02 11:03:44 +04:00
rlsu9 275dce4700 update 2024-12-02 10:53:14 +04:00
rlsu9 83fc3449e8 update 2024-12-02 10:44:00 +04:00
rlsu9 e96f359236 update 2024-12-02 05:12:47 +04:00
rlsu9 e89273a0da update 2024-12-02 04:18:38 +04:00
rlsu9 407e918676 runlong 2024-12-02 02:55:26 +04:00
rlsu9 94d86c168b wandb offline and dir 2024-12-02 01:31:24 +04:00
rlsu9 5a4c227572 update 2024-12-02 00:50:03 +04:00
rlsu9 554f934d37 update 2024-12-02 00:46:34 +04:00
rlsu9 51b72e7434 update 2024-12-01 23:05:29 +04:00
rlsu9 ebfbf6046a update 2024-12-01 21:56:36 +04:00
rlsu9 892324ae59 typo 2024-12-01 21:44:29 +04:00
rlsu9 b66e1a0427 new script 2024-12-01 21:40:25 +04:00
Hao Zhang 02ff44fcd1 update experiment 10 2024-12-01 05:43:24 +00:00
Hao Zhang eb551efe7f update scripts 2024-12-01 05:38:39 +00:00
rlsu9 4af3a99f9e typo 2024-12-01 09:36:42 +04:00
rlsu9 b3d16e0284 typo 2024-12-01 07:58:24 +04:00
rlsu9 c466fe9d73 Merge branch 'main' of https://github.com/jzhang38/FastVideo-OSP into peiyuan 2024-12-01 07:38:25 +04:00
rlsu9 494129344f debug gradient accumulation loss 2024-12-01 07:38:13 +04:00
Hao Zhang 8b9ecfdbcb update gitignore 2024-12-01 02:04:18 +00:00
rlsu9 58440f43de Merge branch 'main' of https://github.com/jzhang38/FastVideo-OSP into peiyuan 2024-12-01 05:26:04 +04:00
rlsu9 c8238e1f7b typo 2024-12-01 05:25:23 +04:00
Zhang Peiyuan 5ff08541f6 [Debug] Typo (#65) 2024-11-30 17:14:14 -08:00
rlsu9 f771899001 update 2024-12-01 05:13:51 +04:00
rlsu9 c609c28e63 update 2024-12-01 05:04:33 +04:00
rlsu9 c19f72f722 typo 2024-12-01 04:44:42 +04:00
rlsu9 43b4778474 Merge branch 'main' of https://github.com/jzhang38/FastVideo-OSP into peiyuan 2024-12-01 04:44:29 +04:00
Zhang Peiyuan 08f5489406 [Feat & Debug] fix uncond; multi guidance validaiton; multiphase schedule; linear range (#64) 2024-11-30 16:43:24 -08:00
rlsu9 7e6e52e02a update 2024-12-01 04:39:44 +04:00
rlsu9 e4114d8fd4 merge main 2024-12-01 04:35:01 +04:00
rlsu9 a19ed188c8 add script 2024-12-01 04:32:22 +04:00
rlsu9 6d3a71b681 linear range; fix uncond; multi guidance validation 2024-12-01 04:31:53 +04:00
Zhang Peiyuan 81103cd48d [Feat] EMA Distill; Distributed validation (#63) 2024-11-29 21:46:40 -08:00
rlsu9 a3d4a1cef4 add gupload 2024-11-30 09:41:37 +04:00
rlsu9 954dc8e35c distributed validation 2024-11-30 09:39:00 +04:00
rlsu9 278e8bb8f3 Merge branch 'main' into peiyuan 2024-11-30 05:28:37 +04:00
rlsu9 b378896b82 readme 2024-11-30 05:28:02 +04:00
rlsu9 1d2a7f233c distributed validation 2024-11-30 05:24:05 +04:00
rlsu9 b4aed1721f add aws efo env 2024-11-30 03:44:43 +04:00
rlsu9 3447ded21b revert to sp=4, sp bs=2, full shard 2024-11-30 03:43:39 +04:00
rlsu9 0c01223d3d update script; no sp 2024-11-30 02:51:22 +04:00
rlsu9 f8089afbf1 ema 2024-11-30 02:44:36 +04:00
rlsu9 2b0c1e66cb update env 2024-11-29 22:52:19 +04:00
rlsu9 79e7dac0ac ok 2024-11-29 21:50:49 +04:00
rlsu9 2b3f3cddd4 remove hardcode 2024-11-29 19:35:30 +04:00
rlsu9 064195363c remove harcode 2024-11-29 19:34:02 +04:00
rlsu9 ed1e17f37f add ema transformer 2024-11-29 11:42:17 +04:00
rlsu9 e32d137aec add ema_transform 2024-11-29 11:11:46 +04:00
rlsu9 62a5530c21 add 2024-11-29 11:08:32 +04:00
rlsu9 b3be22e1e2 add upload command 2024-11-29 09:44:13 +04:00
rlsu9 7156b8d7d5 typo 2024-11-29 09:12:22 +04:00
Zhang Peiyuan 6dd7980ec2 [Feat] Refactor GAN; State saving & Resume; Experiments script (#59) 2024-11-28 21:09:31 -08:00
Zhang Peiyuan b3c54b9e5b [Feat] Training precision (#57) 2024-11-27 16:25:07 -08:00
Zhang Peiyuan 333488ac09 [Feat][Debug] linear quadratic distill; HF precision bug (#56) 2024-11-27 15:13:20 -08:00
Zhang Peiyuan c7526707cc [Fix] Squeeze bug (#55) 2024-11-26 13:29:03 -08:00
Zhang Peiyuan a0ffbe2927 [Feat] PCM Distill; Refactor FM logit to be compatible with all SD3/Flux scheduler. (#54) 2024-11-26 12:26:24 -08:00
rlsu9andRunlong faef037f2e [feat]: Add batchy data preprocess (#53)
Co-authored-by:Runlong <rlsu9@ucsd.edu>
2024-11-25 21:52:36 -08:00
rlsu9andrunlong 9c45a15f53 [feat]: Add Image-Video Mixture training to main repo (#50)
Co-authored-by: runlong <r3su@ucsd.edu>
2024-11-24 14:36:45 -08:00
Zhang Peiyuan e6ff7ae2a3 Resolve config bug and seed (#51)
Co-authored-by: Peiyuan Zhang <a1286225768@gmail.com>
2024-11-15 20:29:48 -08:00
Zhang Peiyuan 897afb8b94 Add LADD (#45)
Co-authored-by: Peiyuan Zhang <a1286225768@gmail.com>
2024-11-15 19:28:41 -08:00
f8178a5a14 add lr scheduler; precision bug fix; add naive dataloader resume (#49)
Co-authored-by: Peiyuan Zhang <a1286225768@gmail.com>
Co-authored-by: Yongqi Chen <yongqich@gl1712.arc-ts.umich.edu>
Co-authored-by: Yongqi Chen <yongqich@gl-login3.arc-ts.umich.edu>
Co-authored-by: Yongqi Chen <yongqich@gl-login1.arc-ts.umich.edu>
2024-11-14 19:57:38 -08:00
4c76b3cc7a [Feat] Lora resume (#48)
Co-authored-by: Peiyuan Zhang <a1286225768@gmail.com>
Co-authored-by: Yongqi Chen <yongqich@gl1712.arc-ts.umich.edu>
Co-authored-by: Yongqi Chen <yongqich@gl-login3.arc-ts.umich.edu>
Co-authored-by: Yongqi Chen <yongqich@gl-login1.arc-ts.umich.edu>
2024-11-12 22:30:58 -08:00
3e0e8cf534 Add lora (#47)
Co-authored-by: Yongqi Chen <144848849+BrianChen1129@users.noreply.github.com>
Co-authored-by: Yongqi Chen <yongqich@gl1712.arc-ts.umich.edu>
Co-authored-by: Yongqi Chen <yongqich@gl-login3.arc-ts.umich.edu>
Co-authored-by: Yongqi Chen <yongqich@gl-login1.arc-ts.umich.edu>
2024-11-11 13:12:14 -08:00
Zhang Peiyuan 635fb2350d [Refactor] Switch to FSDP (#42) 2024-11-09 15:46:25 -08:00
Zhang Peiyuan a52f29374c No checkout mochi 2024-11-07 20:49:14 -08:00
rlsu9andhaoanyscale 31827c9e0a [feat]: Add adaptive fps dataloader and remove redundant code (#41)
Co-authored-by: haoanyscale <c-hao.zhang@anyscale.com>
2024-11-06 19:52:48 -08:00
rlsu9andhaoanyscale 74688e56b5 [feat]: Add vae encoder embedded generator to main (#30)
Co-authored-by: haoanyscale <c-hao.zhang@anyscale.com>
2024-11-06 11:58:15 -08:00
Zhang Peiyuan e56b2ae0c4 Add validation logging with SP (#36) 2024-11-05 14:46:20 -08:00
Zhang Peiyuan 6c6d4b34e7 [Feat] Sequence Parallel (#31) 2024-11-05 08:13:01 -08:00
Zhang Peiyuan 93d6ee49ba Merge pull request #25 from jzhang38/peiyuan
SP inference and Overfit training done.
2024-11-01 17:27:30 -07:00
rlsu9 e678eeb2dc Merge branch 'main' of https://github.com/jzhang38/FastVideo-OSP into peiyuan 2024-11-02 04:26:41 +04:00
rlsu9 432403b12d SP inference done! 2024-11-02 04:21:45 +04:00
rlsu9 8e899953ff Merge branch 'hl/diffusers' of https://github.com/jzhang38/FastVideo-OSP into peiyuan 2024-11-01 20:41:49 +04:00
rlsu9 fd80dc653d switch to deepspeed dummyoptim 2024-11-01 20:41:05 +04:00
foreverpiano 9fb510b618 fix some bugs; still output green 2024-11-01 12:30:38 +00:00
rlsu9 97f48ef433 Merge branch 'hl/diffusers' of https://github.com/jzhang38/FastVideo-OSP into peiyuan 2024-11-01 04:44:23 +04:00
rlsu9 5975deed62 OK 2024-11-01 04:26:21 +04:00
rlsu9 60c420731d Add zero3 2024-10-31 23:42:49 +04:00
rlsu9 a9a66a22a0 Debug successful! 2024-10-31 23:20:46 +04:00
Zhang Peiyuan fd415488df Merge pull request #21 from jzhang38/data_preprocess
[feat]: update data processor with multi GPU data parallel
2024-10-30 17:38:37 -07:00
haoanyscale a496c1c656 update data preprocess 2024-10-31 00:13:05 +00:00
rlsu9 2788f9351a Merge pull request #20 from jzhang38/main
Merge pull request #18 from jzhang38/peiyuan
2024-10-30 17:10:17 -07:00
rlsu9 5209b6ebdd debugging .. 2024-10-30 21:25:48 +04:00
foreverpiano db2c68e879 update inference sp code / can run / still has bug / don't output normal mp4 2024-10-30 16:36:50 +00:00
rlsu9 682774d730 Merge pull request #18 from jzhang38/peiyuan
[feat]: Merge training code into main branch
2024-10-30 09:29:50 -07:00
foreverpiano 2f4d6caa90 rename 2024-10-30 12:43:53 +00:00
haoanyscale dcd8e95c7b fix typos in readme and latent dataset debug file 2024-10-30 05:47:51 +00:00
a1286225768@gmail.com 9e2c9eaa01 overfitting .... 2024-10-30 04:14:04 +00:00
Peiyuan Zhang 567f9f66f8 debug 2024-10-29 21:10:50 +00:00
foreverpiano 48a82aba37 sp enable & still has bug 2024-10-29 15:28:27 +00:00
foreverpiano 4143cd1f95 random seed args 2024-10-29 15:27:52 +00:00
foreverpiano 5b3bffcca9 small bug 2024-10-29 14:17:54 +00:00
foreverpiano 37b091f2ef load 2024-10-29 12:47:48 +00:00
foreverpiano 70f3407032 update optimizer 2024-10-29 12:42:04 +00:00
Peiyuan Zhang d22d40c74a 14 2024-10-29 03:47:08 +00:00
Peiyuan Zhang 6fe5521667 Update generate_synthetic.sh and deepspeed_zero2_config.yaml 2024-10-29 01:00:31 +00:00
Peiyuan Zhang d1422b646d ok 2024-10-29 00:39:26 +00:00
Peiyuan Zhang d4e071be20 training 2024-10-29 00:38:40 +00:00
Peiyuan Zhang 7455bc9e7f commit first 2024-10-28 23:39:15 +00:00
Peiyuan Zhang 45c89c46c5 commit first 2024-10-28 21:46:01 +00:00
Peiyuan Zhang 7ec6f8f720 Deleted unnecessary files 2024-10-28 19:21:00 +00:00
Peiyuan Zhang cd6f8f14f1 remove files 2024-10-28 17:56:34 +00:00
Peiyuan Zhang 8824f74609 clean up name changing 2024-10-28 17:54:38 +00:00
Peiyuan Zhang 1ff9d45044 Remove OSP modeling 2024-10-28 17:53:13 +00:00
Peiyuan Zhang ffe11218dd Change name to fast video 2024-10-28 17:52:49 +00:00
Peiyuan Zhang 6c723e75f3 amend log validation 2024-10-28 17:50:34 +00:00
Peiyuan Zhang 4c3a83a0b3 Delete Open Sora Plan Modeling 2024-10-28 17:20:12 +00:00
Peiyuan Zhang d8489bf368 Generate synthetic dataset 2024-10-28 00:44:02 +00:00
Peiyuan Zhang f6a6366c58 Original pipeline 2024-10-27 23:30:04 +00:00
Peiyuan Zhang 5f8b952ede typo 2024-10-27 22:57:54 +00:00
Peiyuan Zhang a07aee80c3 Mochi Inferenfce & Diffusers 2024-10-27 22:57:14 +00:00
Peiyuan Zhang 235b6498b0 Refactor OpenSora sample_t2v.py and update download_hf 2024-10-26 21:59:22 +00:00
Peiyuan Zhang a89be390e7 remove vae loss 2024-10-26 19:20:04 +00:00
Peiyuan Zhang 3b8c76ea64 Remove files in causalvae 2024-10-26 19:06:46 +00:00
Peiyuan Zhang 63950da0d4 normalize 255; vae reconstruct 2024-10-26 18:57:07 +00:00
Peiyuan Zhang f245e4b4f8 Add mochi download & Change output dir 2024-10-26 18:08:50 +00:00
Peiyuan Zhang 1a8f9196ea Delete merge_data.txt 2024-10-26 18:00:16 +00:00
Peiyuan Zhang ea372da285 Remove unused adaptor files 2024-10-26 17:59:04 +00:00
Peiyuan Zhang fac510d043 Remove unused arguments in train_t2v_diffusers.py 2024-10-26 17:54:43 +00:00
Peiyuan Zhang b6b1a2aa92 Update T5Base 2024-10-26 17:53:51 +00:00
Peiyuan Zhang 464c8a421f Update PyTorch installation command 2024-10-26 17:36:23 +00:00
Peiyuan Zhang 602bf19d93 Update model path and cache directory 2024-10-25 10:21:31 +00:00
Peiyuan Zhang 84cf3b6795 Update t2v_debug_multi.sh with video_length_tolerance_range and dataloader_num_workers 2024-10-25 09:58:41 +00:00
Peiyuan Zhang 83a0280a14 update version 2024-10-25 09:22:16 +00:00
Peiyuan Zhang 182f4082f5 Update max height and width for video processing 2024-10-25 04:28:31 +00:00
Peiyuan Zhang 8d3f651217 Add pretrained model for OpenSoraT2V-ROPE-L 2024-10-25 04:26:57 +00:00
Peiyuan Zhang 330717768d include pretrained open-sora 2024-10-25 04:17:36 +00:00
Peiyuan Zhang ef653171dd Merge branch 'peiyuan' of https://github.com/jzhang38/FastVideo-OSP into peiyuan 2024-10-25 03:57:05 +00:00
Peiyuan Zhang 15fbad6dd5 Remove UDIT and inpaint 2024-10-25 03:55:15 +00:00
Peiyuan Zhang c00cc4b531 Update PyTorch index URLs and video length tolerance range 2024-10-25 03:18:16 +00:00
Peiyuan Zhang 1f423fca06 Fix warning with dataset handling and model loading 2024-10-25 02:31:07 +00:00
rlsu9 2cc0e17ade fix typo for dataset download 2024-10-25 01:40:26 +00:00
Peiyuan Zhang b1564eb141 Remove compress kv 2024-10-25 00:34:07 +00:00
Peiyuan Zhang 97f2b7fdaa Delete npu related stuff and remove inpaint module 2024-10-24 22:57:31 +00:00
Peiyuan Zhang 83825e2060 Update EMA model and t2v_debug.sh script 2024-10-24 22:19:48 +00:00
Peiyuan Zhang da9c1ab7c1 Update torchvision imports 2024-10-24 22:11:25 +00:00
Peiyuan Zhang 7c5b0a6ccd Remove all npu code 2024-10-24 21:35:27 +00:00
Peiyuan Zhang 5f21e3a979 Delete unused files and code 2024-10-24 21:09:24 +00:00
Peiyuan Zhang b47585c68d Update dependencies; Setup code for debugging 2024-10-24 21:01:32 +00:00
Peiyuan Zhang eb1669dab7 Add environment setup and training instructions to README.md 2024-10-24 17:47:34 +00:00
jzhang38 c1eb81f0f9 Remove NPU related code and update training process 2024-10-24 02:36:18 +00:00
jzhang38 8fb5c38381 Remove unused scripts and update TODO list 2024-10-24 02:27:03 +00:00
jzhang38 6e313fad97 Delete unnecessary files 2024-10-24 02:23:33 +00:00
Guangyi Liuandguangyi 294993ca78 [fix] fix the path typo for google/mt5-xxl in gradio_web_server.py (#405)
* [fix] fix the path typo for google/mt5-xxl in gradio_web_server.py

* [fix] fix the issue: the cache of pretrained mt5-xxl weights is inconsistent.

---------

Co-authored-by: guangyi <guangyi.liu@mbz-h100-029.core42.ai>
2024-08-23 11:14:30 +08:00
lb203 de7fc3150a Update train_inpaint.sh
do not set seed
2024-08-20 15:10:56 +08:00
lb203 eb1311b9a2 Update README.md 2024-08-20 11:23:51 +08:00
lb203 d3ea50fc05 Update Report-v1.2.0.md
add 29x480p link
2024-08-20 11:22:06 +08:00
yunyang GeandLinB203 842435c016 release Open-Sora Plan v1.2.0 i2v (#389)
* gitignore

* inpaint

* Create condition_image_path.txt

* Rename condition_image_path.txt to condition_images_path.txt

* Update sample_inpaint.py

* Update sample_inpaint.sh

* inpaint

* fix bug

* Update README.md

* inpainting

* release v1.2.0 i2v

* release v1.2.0 i2v

* Update Report-v1.2.0.md

* Update pipeline_inpaint_sp.py

* Update sample_inpaint_ddp.py

* Update sample_inpaint_sp.py

* Update sample_inpaint.py

* Grammar Error Correction

* Grammar Error Correction

---------

Co-authored-by: LinB203 <2267330597@qq.com>
2024-08-14 12:39:51 +08:00
lb203 394c6444aa Update train_t2v_diffusers.py 2024-08-05 15:23:05 +08:00
lb203 7ef00d7749 Update Report-v1.2.0.md 2024-08-01 13:06:37 +08:00
lb203 16e3afed62 Update README.md 2024-08-01 13:05:36 +08:00
lb203 3c08cb2fef Delete opensora/train/train_t2v_diffusers_lora.py
lora bug
2024-07-27 23:20:25 +08:00
LinB203 74744be314 fix sample 2024-07-27 07:59:13 +00:00
lb203 cc4ba38e1a Update README.md 2024-07-26 21:42:19 +08:00
lb203 39e00fd1c4 Update Report-v1.2.0.md 2024-07-26 21:40:26 +08:00
lb203 adb2a20a3d Merge pull request #352 from cxh0519/main
Update Report-v1.2.0.md
2024-07-25 14:12:33 +08:00
lb203 a6eb95f471 Merge branch 'main' into main 2024-07-25 14:11:05 +08:00
lb203 f0667d8db2 Update Report-v1.2.0.md 2024-07-25 14:10:17 +08:00
lb203 20b395624b Update README.md 2024-07-25 14:09:12 +08:00
Xinhua Cheng 40e0423a1e Update Report-v1.2.0.md 2024-07-25 14:05:45 +08:00
lb203 7e42eef228 Update Report-v1.2.0.md 2024-07-25 13:26:35 +08:00
lb203 08ae0a8379 Update t2v_datasets.py 2024-07-24 21:38:47 +08:00
lb203 b50b51ad92 Update Report-v1.2.0.md 2024-07-24 19:48:17 +08:00
lb203 a4300446d7 Update Report-v1.2.0.md 2024-07-24 19:46:43 +08:00
lb203 ebdfdc49e7 Update Report-v1.2.0.md 2024-07-24 19:46:14 +08:00
lb203 fbf13b7688 Update pyproject.toml 2024-07-24 19:45:28 +08:00
lb203 3a8c34efd0 Update README.md 2024-07-24 19:14:11 +08:00
lb203 ae5679185c Update Report-v1.2.0.md 2024-07-24 18:32:15 +08:00
lb203 067870f28f Update README.md 2024-07-24 18:32:02 +08:00
LinB203 535cb6330f release v1.2.0 2024-07-24 10:31:04 +00:00
lb203 b08681f697 Update Report-v1.1.0.md 2024-06-11 16:40:10 +08:00
lb203 d3ea240481 Update README.md 2024-06-07 18:35:08 +08:00
lb203 40bb7a55d7 Rename sample_video_513.sh to sample_video_221.sh 2024-06-01 21:25:35 +08:00
lb203 27c7046472 Update sample_video_513.sh 2024-06-01 21:25:27 +08:00
lb203 8d62c7273e Update gradio_utils.py 2024-06-01 18:28:18 +08:00
lb203 9dd3c8c494 Update README.md 2024-06-01 18:27:03 +08:00
lb203 46566a713d Update gradio_web_server.py 2024-06-01 18:24:50 +08:00
lb203 fb21d9938a Merge pull request #290 from Linzy19/0528lzy
fix the bug
2024-05-28 18:08:32 +08:00
lb203 be284a0274 Update README.md 2024-05-28 18:07:33 +08:00
ZongyingLin c58d27384a fix the bug 2024-05-28 15:16:49 +08:00
lb203 c421a6ed11 Merge pull request #286 from qqingzheng/causalvideovae-docs
Update CausalVideoVAE docs
2024-05-28 00:40:19 +08:00
New User 336403dd98 fix vis 2024-05-28 00:34:03 +08:00
New User 23aeb03f91 fix train bug 2024-05-27 23:50:36 +08:00
lb203 1a0872ac8e Update LICENSE 2024-05-27 23:40:13 +08:00
Zongjian 0360c1b6be [docs] update CausalVideoVAE docs 2024-05-27 23:36:18 +08:00
New User 559fbf3c36 fix wrong code 2024-05-27 23:33:49 +08:00
lb203 183b05173a Update t2v_datasets.py 2024-05-27 23:01:17 +08:00
lb203 ebefa85284 Update train_t2v.py 2024-05-27 23:00:56 +08:00
lb203 b2976643f8 Update train_t2v.py 2024-05-27 22:59:19 +08:00
lb203 b5b2c0968e Update modeling_latte.py 2024-05-27 22:57:34 +08:00
lb203 dc12340706 Update dataset_utils.py 2024-05-27 22:54:38 +08:00
lb203 b2a50079ac Update README.md 2024-05-27 21:01:02 +08:00
lb203 c9a7881dc5 Update pyproject.toml 2024-05-27 19:44:45 +08:00
lb203 71597994d1 Merge pull request #285 from cxh0519/patch-1
Update Report-v1.1.0.md
2024-05-27 19:44:26 +08:00
Xinhua Cheng 5b78e8e00f Update Report-v1.1.0.md
solve typos
2024-05-27 19:37:15 +08:00
YuanLi 858696d591 Update LICENSE 2024-05-27 19:20:26 +08:00
lb203 2a8b2328a5 Update README.md 2024-05-27 17:42:43 +08:00
lb203 f920d640d0 Update README.md 2024-05-27 17:12:39 +08:00
lb203 1e16f6be29 Update README.md 2024-05-27 16:39:16 +08:00
lb203 194ee0307a Update README.md 2024-05-27 16:33:23 +08:00
lb203 06eedf5ea3 Update README.md 2024-05-27 16:28:09 +08:00
lb203 a19488e33a Update README.md 2024-05-27 16:27:58 +08:00
lb203 60773f4860 Update README.md 2024-05-27 16:11:40 +08:00
lb203 da48eca111 Update README.md 2024-05-27 16:08:09 +08:00
lb203 e3e81fd4f1 Update README.md 2024-05-27 15:57:42 +08:00
lb203 91be347ad2 Update README.md 2024-05-27 15:51:22 +08:00
lb203 b3b0d60536 Update README.md 2024-05-27 15:47:46 +08:00
lb203 6e5515df28 Create Report-v1.1.0.md 2024-05-27 15:44:58 +08:00
lb203 732c672cb4 Update README.md 2024-05-27 15:44:27 +08:00
lb203 e2ae46b718 Update README.md 2024-05-27 15:44:00 +08:00
lb203 9cd5a906fd Merge pull request #284 from PKU-YuanGroup/dev
released v1.1.0
2024-05-27 15:43:39 +08:00
LinB203 27a98335b9 update prompt 2024-05-27 07:41:41 +00:00
LinB203 65ec02d036 5.27 2024-05-27 03:47:55 +00:00
LinB203 c21ea81533 fix demo 2024-05-26 07:39:11 +00:00
LinB203 8aebbc64c0 prepare scripts 2024-05-26 04:17:03 +00:00
root de3f7d8a9f prepare release 2024-05-25 02:54:40 +00:00
root 9b2951969f 5.15 2024-05-15 12:29:03 +00:00
root cfd61fdbb5 fix mask 2024-05-04 12:48:09 +00:00
root 78272b0941 update 2024-05-04 01:49:56 +00:00
root aa6d088e91 train vis 2024-04-30 15:23:43 +00:00
node106 594d98265b fix dataset 2024-04-29 13:15:41 +00:00
LinB203 8dc49b8a6b multi-data 2024-04-29 19:01:10 +08:00
LinB203 5e3a3c6f78 mask loss 2024-04-27 14:53:23 +08:00
LinB203 e767ef3a2e update dataset 2024-04-22 11:10:56 +08:00
LinB203 e92a28ba49 fix rope with compress 2024-04-21 23:30:46 +08:00
root 8358b3014c compress kv and rope pi 2024-04-21 11:44:26 +00:00
LinB203 3287e525c5 abs and rope 2024-04-17 15:45:54 +00:00
LinB203 c59023066e vae temporal tiling 2024-04-16 16:49:43 +00:00
LinB203 350138480f support newvae 2024-04-15 15:04:35 +00:00
LinB203 f1086e192c img training 2024-04-15 12:27:54 +00:00
LinB203 1323daa7b3 read image from folder 2024-04-14 12:03:04 +00:00
LinB203 8a6db0b399 refactor dynamic training 2024-04-14 11:37:16 +00:00
LinB203 8fa3e614a1 add 2drope and dynamic training 2024-04-14 02:04:14 +00:00
lb203 bec0e85238 Update pyproject.toml 2024-04-13 19:58:11 +08:00
lb203 098ecbbd5d Update Report-v1.0.0.md 2024-04-12 14:21:12 +08:00
YuanLi 8d3cd692e0 Update LICENSE 2024-04-12 09:49:31 +08:00
lb203 0183e89cb7 Merge pull request #218 from qqingzheng/vae_rec
Updated content related to VAE reconstruction
2024-04-11 19:06:38 +08:00
lb203 58b64d2662 Update README.md 2024-04-11 16:10:40 +08:00
qqingzheng f58e57d8f5 [refactor] fix hardcode 2024-04-11 03:56:55 +00:00
qqingzheng cdc626b14e [docs] fix typo 2024-04-11 02:36:10 +00:00
qqingzheng 8349763576 [feat] add time chunk inference 2024-04-11 02:31:20 +00:00
qqingzheng 02ad56275d [docs] update inference example. 2024-04-11 02:30:59 +00:00
lb203 461a4b2c97 Merge pull request #214 from JJJYmmm/fix_name_error_emavq
[fix]: Fix variable naming errors
2024-04-10 23:20:28 +08:00
lb203 65a3f0fe8a Merge pull request #207 from AlonzoLeeeooo/main
Fix typos
2024-04-10 23:17:53 +08:00
lb203 0cf62a3e0c Merge pull request #206 from digger-yu/patch1
fix typo
2024-04-10 23:17:15 +08:00
JJJYmmm e2492578c7 [fix]: Fix variable naming errors 2024-04-10 19:40:55 +08:00
USTC-liuchang d581ba621a Fix typos
line 24: `github -> GitHub`
line 54: `a -> an`
line 85: `re-organizes -> re-organize, modulizes -> modulize`
line 87: `opened -> open` (modified according to the changelogs of other dates)
line 94: `a -> an`
2024-04-10 11:51:18 +08:00
digger yu d65994469a fix typo 2024-04-10 08:59:00 +08:00
lb203 193b0398a8 Update README.md 2024-04-10 01:50:40 +08:00
lb203 e08fe61f2b Delete assets/we_want_you.jpg 2024-04-10 01:45:49 +08:00
lb203 c3cd4da606 Merge pull request #201 from qqingzheng/make_vae_better
[docs] update docs and train.sh

Former-commit-id: af001aec7d9bbf38d1e7e1f6a8ace5a77670b85e [formerly e6c3c58c77c2d8fdab1d5b464cd861ff78cc2e43]
Former-commit-id: 6ad032635deb1854b76d5a63a67f10442db0e655
2024-04-09 21:04:29 +08:00
qqingzheng a4fe6a634d [docs] update train.sh
Former-commit-id: eeb00ac046692bc97a064ec1b47c994436798ab1 [formerly 6d0fd85e1b13a7824b8181ba9ccebec2a3c76d40]
Former-commit-id: 1e8e669ad9967aeeeb7622bc04a0759f348cb26f
2024-04-09 13:03:34 +00:00
qqingzheng 933141c5ea [docs] add evaluation detail
Former-commit-id: c15a717cc61159e5f6adafb718237ab578ac81e7 [formerly 9e92772776fa4dd18772c7fec939a42ad6dfbc0a]
Former-commit-id: 98c2a38af5064f27888d1b102c9fded87d2420d5
2024-04-09 12:58:13 +00:00
qqingzheng 3f92ec2c53 [fix] fix bug in #185
Former-commit-id: d74efbd0195380ca383598c06d3d8185dd9cc9bc [formerly 0f2687266bc2271e11b2f06edfe514f466e57b0f]
Former-commit-id: cb6bb234befc49b3870c5690653469a0714890c5
2024-04-09 12:48:32 +00:00
qqingzheng 71541c766a [docs] update docs and train.sh
Former-commit-id: 1d9358e84d12863681b396c7621ae7244caa4dc2 [formerly b801491889b3abad1211225d7f07af3ae0389895]
Former-commit-id: 9e6a59ae2f246b50ace0a033cbd6548660241204
2024-04-09 12:43:19 +00:00
lb203 0623ee9a36 Update train_t2v_feature.py
Former-commit-id: 4a4f7ea2366f1dff5669d6d4834238ebd790e6e2 [formerly ca7d3158fb01f8e7228f833cea8e6741be127c2a]
Former-commit-id: 389f0e7dc66826026046b8e12d7a9f8692d32e42
2024-04-09 19:56:14 +08:00
lb203 4e54046c5f fix using pretrained bug
Former-commit-id: 2dfbb0683b2f3bd1a1d619e5e4fabb5bd4c92d79 [formerly 27f352e822f732cb351d64ac5726c5df3b62c1bb]
Former-commit-id: 722d60ae5ef28499c47292e0a4807a87b9658b01
2024-04-09 19:55:49 +08:00
lb203 326b6cbbe6 Update train_videoae_65x512x512.sh
Former-commit-id: 8e40db106efa2fd879cca42bd9ce2d9b79d777f8 [formerly 3e11781b045a838a5aa98ea75e274198f2b26a44]
Former-commit-id: f3b0804a7cf063e7ff04ee57dccee0320c1f32a5
2024-04-09 18:33:53 +08:00
lb203 71eb96c306 Update train_videoae_65x256x256.sh
Former-commit-id: b2f5cfe72452dfb369aba166e4a101dfcf5758c9 [formerly 557b78ab38a61d7520e91044137f818e50ec24cb]
Former-commit-id: 0e46c9f261e7f5fd4d08e3d7735c17c7975b0e72
2024-04-09 18:33:17 +08:00
lb203 a20766c262 Update README.md
Former-commit-id: be00a17729ac889493f63fd1d649054d7980ca42 [formerly 9b4d8dcfc8e6e2abe4ca727e01561d27d1ba3968]
Former-commit-id: f1b6f5013b99d0d288af0f05c46cb8300d79a8aa
2024-04-09 17:13:42 +08:00
YuanLi 72aef089ff Update README.md
Former-commit-id: 68eaf2e6b00266cf0858b33f9b4d09681efbd2bc [formerly d8dcad250ed8357964ab8ee570b9973b45e29fcb]
Former-commit-id: 75f51b3d84203be3672f6b07bb3c70ba0ae5556c
2024-04-09 16:56:19 +08:00
YuanLi 9b011137b3 Update README.md
Former-commit-id: c48eba0bb15d594007809d4cc605dc46ba029cec [formerly 7deb8a0decf7a9757af4475e3029d415d78d185f]
Former-commit-id: 7f43bb2f1d9308bd08154171d78e9b36e00a837f
2024-04-09 16:50:28 +08:00
YuanLi 14dacb1ca1 Update README.md
Former-commit-id: 54bad83bf054a2ff574199931121c686b4e28008 [formerly 06bb190a39a9b98c8de5e385fc304a86cc8c9fb2]
Former-commit-id: 23e8a235d6828d9ab7c02ef59d40fe13a46fa4b1
2024-04-09 16:47:05 +08:00
lb203 fd3198d7db Update README.md
Former-commit-id: 6fd60c73b6ae69d6ad9dc14c7371bd9bff086b44 [formerly 2ed5d5b7bdcd88044da26ca94237c50af7ab47dd]
Former-commit-id: 443c333353963bc1ec64a4946afbe5e17f9b5a87
2024-04-09 15:26:19 +08:00
lb203 1556d341ed Add files via upload
Former-commit-id: 943dd9a063baaa05d7f0d0bd52cbde35cf2b3d98 [formerly 5542359738243a8e948a8f08ed4e8dedf6b4b818]
Former-commit-id: fbee07f6fef2ac86bc15ff66f2e2a1a68b64ed01
2024-04-09 15:25:46 +08:00
lb203 3794a468fa Update Report-v1.0.0-cn.md
Former-commit-id: 83124efeaa5a8cd528a15760bdf88acc403142bd
2024-04-09 13:36:35 +08:00
lb203 b21d386205 Update Report-v1.0.0-cn.md
Former-commit-id: 59edce70edbaed957ba40f1d95b4a5050ece12bf
2024-04-09 11:34:43 +08:00
lb203 9b72cb3e6f Update Report-v1.0.0-cn.md
Former-commit-id: 0edac24fcaa447a534755bf3aac1f2027a491c06
2024-04-09 11:34:17 +08:00
lb203 5b5159e8fc Update Report-v1.0.0.md
Former-commit-id: 3c8eb75dc2045154e8654f860b1fabd7e597094b
2024-04-09 11:33:34 +08:00
lb203 113bb8c5df Update Data.md
Former-commit-id: 15defc1a3846335fd68e18fa9b8ffbe38e3e7100
2024-04-09 11:32:24 +08:00
lb203 4ad069ffdc Update Report-v1.0.0-cn.md
Former-commit-id: d5cf6aed7c1673562a6d2022c3fd7f7b16006cfd
2024-04-09 11:09:02 +08:00
lb203 421aa9b66e Update README.md
Former-commit-id: 0cc27a5b065b61f37d44dc2c90ba2782075eefb2
2024-04-09 11:06:18 +08:00
lb203 8c40057697 Update README.md
Former-commit-id: c437a18dbec7ac6e02287565a84d75f96664ee99
2024-04-09 11:06:05 +08:00
lb203 791a48a088 Update README.md
Former-commit-id: e386ec112337271bb9f55ea6ec872eaba94aff50
2024-04-09 11:02:06 +08:00
lb203 b85795c263 Create Report-v1.0.0-cn.md
Former-commit-id: d484754e080bd65f6b35619b840040581fa6b69c
2024-04-09 11:00:43 +08:00
lb203 bd895c4d90 Update README.md
Former-commit-id: 88e7f2062c494c199caff468f5f14f3165f763de
2024-04-09 09:46:28 +08:00
lb203 4731a994b0 Merge pull request #187 from qqingzheng/add_causalvae_docs
add causalvae doc

Former-commit-id: d4166b1cf6356e4415bbdba315c34e23ffdd0231
2024-04-09 09:39:48 +08:00
Chestnut bf4364b50a 更新 README.md
Former-commit-id: 42607786f3f3d0eba9336f774b0a2ae076cce793
2024-04-09 00:25:46 +08:00
Chestnut 1817a15c17 Update README.md
Former-commit-id: 567ade18047a9cc81648997c5d9287fa8900614d
2024-04-08 23:43:00 +08:00
Chestnut 8bc9abb45b Update Train_And_Eval_CausalVideoVAE.md
Former-commit-id: 156739c35b5dda594138b2e3b1fd6ec99556af23
2024-04-08 23:41:49 +08:00
Chestnut 2dc20a2cd1 Update Train_And_Eval_CausalVideoVAE.md
Former-commit-id: 589657b089930379bb75f3d49063ebb72671efc6
2024-04-08 23:40:07 +08:00
qqingzheng 7d9f03db56 add causalvae doc
Former-commit-id: 4e6d9e038c8edb81f8402834bd01eeeb823924f9
2024-04-08 12:25:43 +00:00
lb203 5e5c6a64dc Update Data.md
Former-commit-id: d9a5c8fbd36a34b7baf720bc27d69604ae5c9d57
2024-04-08 19:28:52 +08:00
lb203 9906697152 Update pyproject.toml
Former-commit-id: bb037420b75303b58486ba79da9180b2bf63cf88
2024-04-08 19:00:26 +08:00
LinB203 1f7edca9fd clean
Former-commit-id: a7f2c1c8b2243587cedd6e152e64298842287095
2024-04-08 18:57:06 +08:00
lb203 a7c3aebf27 Update README.md
Former-commit-id: 828be4267f0795969293e4a321e4e0bfa8e1f1e6
2024-04-08 16:08:12 +08:00
lb203 029d7eba30 Update README.md
Former-commit-id: dc923fe2413b3be31d8d88e7dd83a931fcbf9458
2024-04-08 14:44:58 +08:00
lb203 22b86b0e32 Update Report-v1.0.0.md
Former-commit-id: 37f181f34f64ca1141a1345b7c1f2af283be1cad
2024-04-08 14:27:11 +08:00
lb203 0e8162191f Update Report-v1.0.0.md
Former-commit-id: 400f708a080f0799e02697bb8e66d8430ffb1f56
2024-04-08 10:54:11 +08:00
lb203 8139823ff5 Update README.md
Former-commit-id: 2873d0eaedfad392c627a714448118949d7b7e13
2024-04-08 10:40:23 +08:00
lb203 b37a6ff3a7 Update Report-v1.0.0.md
Former-commit-id: 6ebe2c62c0904142026d3796027e95ce43afe16a
2024-04-08 10:37:04 +08:00
lb203 172e1bcc58 Update Report-v1.0.0.md
Former-commit-id: 38b779022418cc41cdf9fc508e461f2f6299fd60
2024-04-07 23:48:08 +08:00
lb203 22f61c0272 Update README.md
Former-commit-id: 9c0f82ae9953b56f2540e9c7ada021e4e1bc6165
2024-04-07 23:47:36 +08:00
lb203 cd99a6759a Merge pull request #183 from chaojie/patch-2
Update README.md fix colab link

Former-commit-id: 257c9275a0bdd8ae931592b7e5cf302f0d97d900
2024-04-07 23:07:21 +08:00
YuanLi 8cd4d9671e Update README.md
Former-commit-id: 5731e810e2efb7ca7eda1aa8954eb7fd260f4250
2024-04-07 22:55:49 +08:00
chaojie 459369d3b6 Update README.md
Former-commit-id: 1b54444249fa91b29334b8fc364fb1978c25fb2d
2024-04-07 22:52:01 +08:00
YuanLi 15113e2e7a Update README.md
Former-commit-id: bbf3cef43a129a25a80ce134a8895796e24353c6
2024-04-07 22:50:49 +08:00
YuanLi 9016110a90 Update README.md
Former-commit-id: c4a976e9b93536299b2e350454c780fec54fbe95
2024-04-07 22:45:48 +08:00
lb203 154070c2d0 Update README.md
Former-commit-id: c1492211ced3cdbec93ef28678a1467245e122e9
2024-04-07 22:26:58 +08:00
lb203 ed570f7b18 Merge pull request #178 from qqingzheng/causalvae_release_pr
Fix some compatibility issues

Former-commit-id: 11af500907302d699b761799408462a0ebfb9b31
2024-04-07 19:45:14 +08:00
qqingzheng 492dbab0d6 fix bugs in inference
Former-commit-id: e17c7a7b7704920cb86894419bf573d0fb0c06fa
2024-04-07 11:36:57 +00:00
qqingzheng 0044ec6623 Fix bugs in inference
Former-commit-id: c251a86ac7c91d6f2bb12ae645628e9cf4b83d3d
2024-04-07 11:11:16 +00:00
lb203 e1fc7291d5 Update README.md
Former-commit-id: ce2bbf82045041495ed448b46d5f4bdba84aa740
2024-04-07 18:46:43 +08:00
lb203 d3bbaa7a55 Update Report-v1.0.0.md
Former-commit-id: 7cec40420601f7da57449586508e50119bd02a61
2024-04-07 18:11:34 +08:00
lb203 d58cc4504a Update README.md
Former-commit-id: 9f926abb08f156807091dd044c133788649a6bac
2024-04-07 16:57:38 +08:00
lb203 d30e3653f2 Update README.md
Former-commit-id: 9bae31c73ea902581e1ee94cfd9012efdf78d349
2024-04-07 16:51:14 +08:00
lb203 b08bf8d907 Add files via upload
Former-commit-id: 9a207435d9efac0b19771df5d2288160af1bdd6e
2024-04-07 16:49:45 +08:00
lb203 d86ff4f933 Update README.md
Former-commit-id: f709d75e7a7d8a08ec60132aa906f6b880af8e58
2024-04-07 16:38:47 +08:00
lb203 79bf57e77c Update Report-v1.0.0.md
Former-commit-id: aea1f4a82a525d3e6e1d1a1bb7631326b294cdcc
2024-04-07 16:33:28 +08:00
lb203 3afaf0c5fe Update Report-v1.0.0.md
Former-commit-id: bd9aa7991212d98a6224b855a3bfb2c12feb5950
2024-04-07 16:31:48 +08:00
lb203 fcd94894da Update README.md
Former-commit-id: f8cb7f38751d7a6ef586c293fb769f5d60ad5c59
2024-04-07 16:30:47 +08:00
lb203 a3cf68c883 Update README.md
Former-commit-id: 30f61958e221c3d41c4aa5917f4511e8c0482cf9
2024-04-07 16:28:34 +08:00
lb203 5df5af0629 Update README.md
Former-commit-id: d5ab411b2e2fd5d6abeda500895e3339167572ab
2024-04-07 16:27:37 +08:00
lb203 deaea23969 Add files via upload
Former-commit-id: a232ec2d98b245a9b502a2c49fc4f468a86fbd64
2024-04-07 16:22:43 +08:00
lb203 3e6abd244d Update README.md
Former-commit-id: 3210474a46845ae3a6c0bde7fb6c7f9845866628
2024-04-07 16:13:48 +08:00
lb203 760029dbfe Update README.md
Former-commit-id: 7d4118566b77e09de4a3615612a5b368c76c293e
2024-04-07 16:12:52 +08:00
lb203 f08fa0b9d5 Update README.md
Former-commit-id: 037d7d3e084d7ff426347db49c4b210a2ee3927d
2024-04-07 15:58:09 +08:00
YuanLi c335b0b70c Update Report-v1.0.0.md
Former-commit-id: 92d906b340f5970a77377586d7295f46b5de99ec
2024-04-07 15:57:37 +08:00
lb203 cdd41c2aa3 Add files via upload
Former-commit-id: 292cbcfa4e4f384fe6958badc27d3067173119f9
2024-04-07 15:57:35 +08:00
lb203 d02d16e6e2 Add files via upload
Former-commit-id: 1ae8512b7846e9faafdb38ca532898d7f1bdcce2
2024-04-07 15:50:18 +08:00
lb203 7434308e92 Update README.md
Former-commit-id: a2ec90a19eacb099cb9f36c1b5dd6e24be307fae
2024-04-07 15:08:09 +08:00
lb203 511ea03617 Update README.md
Former-commit-id: a61200bea2eea4fd22bd8095f192fef4c22c49b4
2024-04-07 15:04:51 +08:00
lb203 8d5f0281ae Update README.md
Former-commit-id: e6fb5d864ac8af8214cdc89c71b42f296dda14e7
2024-04-07 14:59:24 +08:00
lb203 68ec69bc6c Update and rename CausalVideoVAE.md to Report-v1.0.0.md
Former-commit-id: 3b848f8de33cf4f0ed802428e9ad31d2fa26de63
2024-04-07 14:57:39 +08:00
LinB203 ef0157a168 update gradio demo
Former-commit-id: 80c2cc0bcc2a7532bc2440df16c1f811b0b30516
2024-04-07 09:44:23 +08:00
LinB203 20c3149b62 clean
Former-commit-id: 56ed87088e13cdd93929e2ceedbfae693e2f013a
2024-04-06 23:41:01 +08:00
qqingzheng 35f5e4cff8 Fix some compatibility issues
Former-commit-id: 942d8598b28516369780c3519607929869b427b7
2024-04-06 14:08:02 +00:00
LinB203 282f973d9b v1.0.0
Former-commit-id: 93f44f3b425c090d9bc92687a9c50a26b4f0d7c8
2024-04-06 22:04:52 +08:00
lb203 4b8b80835b Merge pull request #177 from qqingzheng/causalvae_release_pr
CausalVideoVAE release version

Former-commit-id: 50dd03b07b4a57e708ca01f703d806e9fc568d2a
2024-04-06 19:48:26 +08:00
qqingzheng a554dcc696 release
Former-commit-id: 52fe2ac6610661d6a13a08390c84a8237f37986a
2024-04-06 11:40:05 +00:00
LinB203 a4a1b93bbc refactor vae to hf
Former-commit-id: a938d3f7f962709f7ecff5e9d49c9bf1ce40d7fa
2024-04-06 19:26:08 +08:00
LinB203 cea0c041df update train script
Former-commit-id: ac16f77d19488cd46130587369cd7a5ea378052b
2024-04-06 13:28:29 +08:00
LinB203 8137d40a92 add tile training
Former-commit-id: 216079dc925beefe1ec722a4e87e46a4e1ca56be
2024-04-04 22:00:38 +08:00
LinB203 e202525517 sample pipeline
Former-commit-id: 8964b16c0dd65445a20050c9a0e82d909b55eaff
2024-04-04 10:50:29 +08:00
LinB203 8084949b14 released v1.0.0
Former-commit-id: 8df5897a4ffc341ced45faf617687fb8ebf1286c
2024-04-04 10:46:29 +08:00
lb203 b3f6d06941 tile only2d
Former-commit-id: 7f31ad03fdbaac97aea51a98bd29dc7327b700c9
2024-04-01 12:27:40 +08:00
lb203 b7f0d770b8 Merge pull request #172 from SamitHuang/fix_attn3d
[Bug fix] Fix reshape bugs in AttnBlock3D in CausalVideoVAE

Former-commit-id: 8a6b0947c126c87d13809adbd0adfdf65716c27f
2024-03-31 15:07:13 +08:00
Samit ee0b749421 fix reshape bugs in AttnBlock3D
Former-commit-id: 299622e168a6cbee14ef2056c47cae722c20e005
2024-03-31 14:52:28 +08:00
LinB203 0c86a4ff11 tile conv
Former-commit-id: 5133615bcba221c4b86ae4e8b09b82ee5d34c66d
2024-03-30 20:42:20 +08:00
LinB203 2aaf448a24 update sample
Former-commit-id: 116726b9d565c689496123d4b6e62b98400536a6
2024-03-30 15:30:29 +08:00
lb203 a50abb7b49 Update __init__.py
Former-commit-id: 2bdc29d86ebff3d6f29c38ded57c7b0dd1e6bbdb
2024-03-28 22:04:27 +08:00
lb203 b88dfd6d1e Update README.md
Former-commit-id: 2d9ae56309717a91e0690bd5c354fe3cbe5d5ed6
2024-03-28 21:16:34 +08:00
lb203 5dc588f47c Update CausalVideoVAE.md
Former-commit-id: fcde4d0ff783448c2006d6f4751a0e4f9cc23d0f
2024-03-28 20:16:49 +08:00
LinB203 f48b3da80a fix videovae trainer
Former-commit-id: 79e1feb412b6eeead3306f7f0d55a01f9b2a543e
2024-03-28 20:04:15 +08:00
LinB203 9462239286 update vae
Former-commit-id: 24298df5d374d5aaa5696f6200d4e23ae887715f
2024-03-28 19:57:15 +08:00
LinB203 c70648b740 update model
Former-commit-id: e4e24650376d9dce974b290752efb416d5061983
2024-03-28 19:10:24 +08:00
LinB203 45187a0d22 fix training bug
Former-commit-id: 09a6283ddd9ab11479f30324de788bd7415702ae
2024-03-28 19:07:46 +08:00
lb203 b88ae0d76d Merge pull request #165 from qqingzheng/add_eval
[feat] add eval code

Former-commit-id: 2b555c515ed71b8f699627423b492a5c43218b84
2024-03-28 19:02:32 +08:00
qqingzheng c564dc569d [feat] eval
Former-commit-id: d2c3cf5ef8d18feb7b0544d68d9796656e90ba8d
2024-03-28 11:00:20 +00:00
lb203 55a595ece8 Update README.md
Former-commit-id: 02b0422fd745b4b7ec091cc6ee81d1d237245fe6
2024-03-27 23:13:29 +08:00
lb203 c7a9f094c8 Update README.md
Former-commit-id: f294a0a28f288ae592e7de004320d3eb5e48e945
2024-03-27 23:13:01 +08:00
lb203 2dbd3bd700 Update README.md
Former-commit-id: 90d6d298eaee6255098b342b31444e7a347fc50e
2024-03-27 23:10:14 +08:00
lb203 c19b099618 Update CausalVideoVAE.md
Former-commit-id: 1cd665f699632e9dc9357379225c085d9c1278d5
2024-03-27 22:59:36 +08:00
lb203 7db5b81522 Update README.md
Former-commit-id: a41674f5ef71ced59b374226dddfa09c15a99f25
2024-03-27 22:57:59 +08:00
lb203 be1eb20b95 Update README.md
Former-commit-id: 8d70a890fc4191bfc98c3aca6dd3c8a70534fb3d
2024-03-27 22:57:40 +08:00
lb203 ce836de93d Rename causalvideovae.md to CausalVideoVAE.md
Former-commit-id: 0a78e4193fcaec4662b7c6465a9d80643b354cd6
2024-03-27 22:55:50 +08:00
lb203 44eb12b157 Create causalvideovae.md
Former-commit-id: 98414c2ad7dd39f740440b2d9059140f93492e83
2024-03-27 22:55:32 +08:00
lb203 5f9ff24a3d Merge pull request #162 from qqingzheng/add_causal_vae
[feat] add causalvae ✨

Former-commit-id: 4c1b27c277f6dee020d7aa9d6f719415f0eed898
2024-03-27 21:43:31 +08:00
qqingzheng ec81e2427c add causalvae
Former-commit-id: ac936276fd3213ee1815dfe096cd64cecb601428
2024-03-27 12:49:30 +00:00
LinB203 f78a599fa3 scripts
Former-commit-id: 047046f684c2831e68e0cf256cb46fc3790cda33
2024-03-25 16:33:14 +08:00
LinB203 6c12429fd2 train t2v feature
Former-commit-id: 7f16b162cae0e3533c8ba9aa03186a846d9e02bf
2024-03-25 16:25:01 +08:00
lb203 c6d7ed5c3f Update Data.md
Former-commit-id: d1c72e3209769d0204efb8e7d705bdf4f22b82ea
2024-03-22 10:30:04 +08:00
lb203 b3fb8cf3c5 Update README.md
Former-commit-id: 859c0f60dac1562b8a6bbb72b793a4709dbc3597
2024-03-21 16:02:23 +08:00
lb203 ebaa135355 Merge pull request #152 from Ytimed2020/main
Add CLIP support and example

Former-commit-id: 3c3f80caa5d24fac1f6bf5c01b4cb8df86f2edfd
2024-03-21 15:59:24 +08:00
lb203 211c7409bc Merge branch 'main' into main
Former-commit-id: e4c99f4b5d084171e3097bc8939d4806f32485a8
2024-03-21 15:59:03 +08:00
lb203 dfef484db5 t2v attention_mode
Former-commit-id: 4fd8bd87e0d0a98d5d0a3201d5db9a5ba055b894
2024-03-20 23:04:02 +08:00
lb203 4d476bc759 Update README.md
Former-commit-id: 95b28706d257d7769049abe30a7121b60e39a53f
2024-03-20 22:35:11 +08:00
lb203 a4b273f255 Update README.md
Former-commit-id: 9065d12ee867c76452ce370fb71cc83bdc01470b
2024-03-20 22:33:39 +08:00
LinB203 6b51d0ccfd support attention_mode
Former-commit-id: c72f354fbfd948e8cd4b0cc63c157bc4688c7665
2024-03-20 22:23:24 +08:00
LinB203 ff36d291d8 train with image
Former-commit-id: 209b9a8ad2f19a50e46f9b7ec68dd781898e491a
2024-03-19 23:21:57 +08:00
Ytimed2020 73ad660277 Update clip.py
Former-commit-id: 1ee53d152630b6acc69369be33287abfb143224d
2024-03-18 23:03:33 +08:00
Ytimed2020 0817d81290 Create clip.py
Former-commit-id: e3397c567efcfeef6f58dfef2eb4251bedbbf33a
2024-03-18 23:01:34 +08:00
Ytimed2020 f2ac960431 Update __init__.py
Former-commit-id: 7c8af2909c4549e96bc0893d09fcc53d71fb6cc7
2024-03-18 23:01:04 +08:00
lb203 81cc4190fd Merge pull request #145 from qqingzheng/add_casual_vqvae
[feat] add casual vqvae ✨

Former-commit-id: f034a4cfe8bc84fee5a50a1da833a39c9499f213
2024-03-18 13:10:12 +08:00
lb203 1f34030723 Update pyproject.toml
Former-commit-id: 5637656a79faba1b397b56918c42022cc209e731
2024-03-17 20:22:03 +08:00
lb203 757268eccd Merge pull request #146 from glgh/doc-fix
[docs]: fix VQVAE training script path

Former-commit-id: 6ea832b958e6c8e5494a7b199874ffce061325aa
2024-03-17 09:41:01 +08:00
gl 83cf1dbd8e [docs]: fix VQVAE script path
Former-commit-id: d5f5c681b8c50622a84256881d193d5803ff3c28
2024-03-16 12:20:59 -07:00
qqingzheng b3c17829e9 [feat] add casual vqvae
Former-commit-id: 89087970b267908c8667984aba42b1ade2505467
2024-03-17 02:46:33 +08:00
lb203 862f627607 Update README.md
Former-commit-id: 6729039f059a23bf71faa944e2498657ef2c7442
2024-03-17 00:00:45 +08:00
lb203 73161c3248 Update train_t2v.py
Former-commit-id: d25b39ffac4474abd40b551fe0e51c421cb7bf5e
2024-03-16 22:23:36 +08:00
lb203 1d1a6a5b63 Update train.py
Former-commit-id: 783faf5cd86c148a713ea986ceed8527b108f2b8
2024-03-16 22:23:22 +08:00
LinB203 085062a53f refactor and fix resume bug
Former-commit-id: 1b1136671b9a7e0b15b70168e2c44dbff04a22e2
2024-03-16 22:21:15 +08:00
LinB203 516082e06c resume and compress kv
Former-commit-id: 0af7d58f88c1b65b4089da6f3e5c70456614da7c
2024-03-15 22:48:09 +08:00
lb203 054bf4bfb0 Update README.md
Former-commit-id: d97edd0e714a237a54f191dcebb6fd39f73185d6
2024-03-15 22:22:42 +08:00
lb203 510434d9a1 Update README.md
Former-commit-id: 34e529fd02712d4466ab2bc1a63f9bd69976b6c3
2024-03-15 20:14:47 +08:00
lb203 befdbd5943 Update pyproject.toml
Former-commit-id: 7fb921440b608e47781d2f541b2a8d893a48193e
2024-03-15 20:13:18 +08:00
LinB203 daee16c393 update scripts
Former-commit-id: 8b2a794095f2deb9b1e8090486cb8242bf81031d
2024-03-15 19:09:18 +08:00
lb203 04034c2e50 Merge pull request #143 from anapple-hub/my-script-branch
[fix]: fix sample.sh

Former-commit-id: 7ceacc5f9544d0e27d8cea4981ed12ee784efd6f
2024-03-15 19:00:35 +08:00
LinB203 d2a8e64a83 del t2v
Former-commit-id: 5daa2952997a29e74e2b5d235001d6d9dabf9ff6
2024-03-15 18:43:44 +08:00
anapple-hub 99bbe2ecbe [fix]: fix sample.sh
Former-commit-id: 09916dfcfb0b80a4217016919e0394a2cb665cfd
2024-03-15 18:30:49 +08:00
lb203 210690e431 Update README.md
Former-commit-id: 7b96fd89eaf3743a4a9fbc995e6a2a791c734f2e
2024-03-15 13:47:29 +08:00
lb203 17c430042e Update sample.sh
Former-commit-id: b149a300f1aff53d9ab6e66a91cc2bcd37900347
2024-03-14 13:21:23 +08:00
lb203 4b8c154784 Update sample.py
Former-commit-id: eb906691abec030d7aa2078b63fc9c7d678662ed
2024-03-14 13:21:04 +08:00
LinB203 99a789bd5d del t2v
Former-commit-id: 910398ca297be8a188d59c59c121857666774af1
2024-03-14 08:51:10 +08:00
lb203 d82c3b9e60 Merge pull request #139 from qqingzheng/fix_vqvae
[bug] add quantization loss

Former-commit-id: 58bb160e834dcd74650741e2003720d6ae5cad5f
2024-03-13 18:47:15 +08:00
qqingzheng 08d8ef6e72 [bug] fix quantization loss
Former-commit-id: 111fcf55f969ffe4c9be284a317ae5712570a527
2024-03-13 18:16:28 +08:00
lb203 51581271b4 Update README.md
Former-commit-id: 2d5b6815f95e94a98847b8a0376473f01bb15d14
2024-03-13 14:02:33 +08:00
lb203 014e5b4933 Merge pull request #130 from sennnnn/dit_deepspeed
⭐ [Feature] Support deepspeed training for DiT

Former-commit-id: 9b25f038f32a03dd56552a132118757d0835c428
2024-03-13 13:40:03 +08:00
lb203 18a652afff Update README.md
Former-commit-id: cf1c56c0058288427c1dfd651c8c0e9a981c5653
2024-03-13 13:33:48 +08:00
lb203 8aa4e60cf4 Update README.md
Former-commit-id: 7e74356a3279b02d062bab9c9f361f61eb756179
2024-03-13 13:22:16 +08:00
sennnnn 9750ead38b Fix typos.
Former-commit-id: 6add5ee7ef39a973e91b7a7c1b3a4b0980130b88
2024-03-12 21:23:44 +08:00
sennnnn 66f085252e merge main branch.
Former-commit-id: 5f78da5eae2b18305bb4a0a6dc7ab771e9b96f60
2024-03-12 21:11:56 +08:00
lb203 f8b0701a4b Merge pull request #123 from yunyangge/main
[docs]: frame interpolation update

Former-commit-id: ced46982cd41903a212a841500618a614e7c9b8a
2024-03-12 14:44:21 +08:00
yunyang Ge 1c72bea528 Merge branch 'PKU-YuanGroup:main' into main
Former-commit-id: 314be102744ec83be3bc37750ea4d6674e383de4
2024-03-12 14:21:45 +08:00
lb203 c8811aa2d5 Update train_256.sh
Former-commit-id: a2dfc9a8c70845446e731c88acd222e9b2db9122
2024-03-12 14:21:14 +08:00
yunyang Ge 07d818282d Update readme.md
Former-commit-id: e287f94838007f2eda434a46bcd250099b627097
2024-03-12 14:19:52 +08:00
yunyang Ge e4ea15e66a Update and rename Frame Interpolation.md to readme.md
Former-commit-id: 87bdf1ebecb002c086497b3c47acb3f3cb2aaf34
2024-03-12 14:19:16 +08:00
yunyang Ge 59e2050bc3 Add files via upload
Former-commit-id: b707b1968fa59d85891040604e7d54bef61b4549
2024-03-12 14:18:00 +08:00
lb203 a0f4a001a3 Update README.md
Former-commit-id: 8ec7524f4f171e650d7a25cc88ed29f7b5017454
2024-03-12 14:16:18 +08:00
yunyang Ge 78b9cb8775 Update interpolation.py
Former-commit-id: e10e3416433e5f396aa13e7d8beaf451ff47a383
2024-03-12 14:13:54 +08:00
lb203 ff617764b7 Merge pull request #104 from sennnnn/videogpt_deepspeed
⭐ [Feature] Support deepspeed for videogpt training.

Former-commit-id: dc639030e3544ca54e9c579624375bdea486a0ef
2024-03-12 14:12:51 +08:00
lb203 f8ca07a1d8 Update sample.py
Former-commit-id: 6e09fc266a626f465109abc199d9fb452657929e
2024-03-12 14:10:10 +08:00
lb203 61306c7510 Update README.md
Former-commit-id: 0d7dd6233811ec3c8741affb436d8004d8c676b8
2024-03-12 14:06:10 +08:00
lb203 429391840f Merge pull request #121 from sysuyy/add_multi_node_script
[feat]: use accelerate on multi-node

Former-commit-id: 67b01dc1d934d3d86d7ecca00c5dd1a11fd4d22d
2024-03-12 14:05:08 +08:00
lb203 aa3ff1e9c3 Update README.md
Former-commit-id: c5eea8d3492872255a6a34d422230509d1c3531c
2024-03-12 13:35:03 +08:00
lb203 e0dac4fb40 Create train_256.sh
Former-commit-id: bf62151617feb49663f8dfe0c78aa01f41e62092
2024-03-12 12:55:41 +08:00
lb203 486218b252 Update README.md
Former-commit-id: 5717aab628fceba311e284d1bdddeacc4c43c7c5
2024-03-12 11:52:28 +08:00
lb203 21383acca7 Update README.md
Former-commit-id: dd00e04220ff5232c5c4503a095e409471476a51
2024-03-12 11:49:20 +08:00
lb203 e4949048e0 Update README.md
Former-commit-id: 266f9f97ea8f327fdefb2ca959c23d08b7084137
2024-03-12 11:47:12 +08:00
lb203 c39a13d6b0 Merge pull request #120 from touale/main
[fix]: correct attention_mode to attention-mode

Former-commit-id: 6deb9393f771edbf8db8a95e7b9f2107b2682c76
2024-03-12 11:00:50 +08:00
sennnnn ddf7e82b61 Update training arguments of videogpt training.
Former-commit-id: c9660af891c0dae1f51a1075ef5b2df012f65e06
2024-03-12 10:30:41 +08:00
sennnnn 064a503c31 use imageio for write video which has better compatibility.
Former-commit-id: 005119dc9f78ea2a611d22a53772fd59d97d7139
2024-03-12 10:30:01 +08:00
sennnnn 91409c89cb Can't fix zero loss bug.
Former-commit-id: 1f32f9d889743b7961b34b823b276bfd03974191
2024-03-12 10:17:24 +08:00
sysuyy 330e46e9e8 [feat]: use accelerate on multi-node
Former-commit-id: 0b12fc31f1d2a63f9da38821174ab63d9b3a2d72
2024-03-11 14:45:23 +00:00
touale 76e172e08c [fix]: correct attention_mode to attention-mode
Former-commit-id: 9957e2eebb2166b02600c6052fb54908f5d12bad
2024-03-11 22:14:34 +08:00
sennnnn 896d5e3657 Fix deepspeed zero loss bug.
Former-commit-id: e24af415bc5d6fd38d72a24d6312f4e65d3627dd
2024-03-11 21:37:23 +08:00
sennnnn a360da1ec7 update videogpt.
Former-commit-id: 2e211563c684a8b6ef62dfc0c4f1897224dfb58d
2024-03-11 20:35:01 +08:00
sennnnn 46126baadf use fp16 temporarily.
Former-commit-id: 93381968e10aae7bbec23ec1ef40e7cb311fddf0
2024-03-11 17:03:23 +08:00
lb203 2eba66af88 Update README.md
Former-commit-id: c2c64665d4f281e264d87c20cc1cfd38e7e5f168
2024-03-11 16:58:01 +08:00
sennnnn a5d891a8bc Add deepspeed script for videogpt training.
Former-commit-id: 3bda2a05cb789fe785b2355a613385b3eb7abbbc
2024-03-11 16:29:11 +08:00
lb203 d1c7015eaa Update README.md
Former-commit-id: abb8ed57a29b1f66adec66d854429f36f9199540
2024-03-11 16:10:31 +08:00
sennnnn 56ed84acbd Add hidden_size argument for videogpt config.
Former-commit-id: 1be9f22767fe9c80ad90cb17184751b97aff9012
2024-03-11 15:46:54 +08:00
sennnnn 9fbd96d66c Merge branch 'main' into videogpt_deepspeed
Former-commit-id: c815b5eae7d60f89df0366f762a9a4afc8c7655e
2024-03-11 15:45:15 +08:00
LinB203 0e2a86b2ac clean dit
Former-commit-id: 117ec4196a6f2cd83da223b993b14e28f7a693f8
2024-03-11 15:44:53 +08:00
sennnnn 59030ac60c Merge branch 'resolution_typo' into videogpt_deepspeed
Former-commit-id: acaac6af0e35fcc611a9ecd15a39d6bb41aed4aa
2024-03-11 14:36:07 +08:00
sennnnn 2b17f4fac2 Merge main branch.
Former-commit-id: 800ca74fad0d9021f1e96ddf32cd93cdb37cbbe0
2024-03-11 14:35:17 +08:00
lb203 523670a478 Merge pull request #117 from sennnnn/resolution_typo
Fix resolution typos

Former-commit-id: b9acfa97f5514513f6c983f3e815300b435d3076
2024-03-11 14:32:59 +08:00
sennnnn 1365640065 Fix resolution typos.
Former-commit-id: 3ad55d28eaf13f9c8fd23912d2691965737527e9
2024-03-11 14:26:05 +08:00
lb203 59e2407366 Merge pull request #97 from HowardLi1984/refiner
[feat]: Caption Refiner

Former-commit-id: 6af3b3689679a99acb741218416dc3a9cde29f45
2024-03-11 14:05:35 +08:00
sennnnn 1321e1f977 refactor dit for supporting deepspeed.
Former-commit-id: e1909745cb05ea2f28f3a391c194f7656593a236
2024-03-11 11:51:46 +08:00
lb203 14e217a698 Update README.md
Former-commit-id: 1f94f2721f35670aeae8dbfb7c0a5abd06cd2aee
2024-03-10 21:37:01 +08:00
lb203 d4aa360c50 Update README.md
Former-commit-id: 2808edf11005e04aa730971a786d1a4e3bca88b5
2024-03-10 21:16:15 +08:00
lb203 93b624e62d Update README.md
Former-commit-id: 64d147863368aeef479ad25f2e5463fdcb76de46
2024-03-10 20:27:46 +08:00
lb203 f423fc7538 Update README.md
Former-commit-id: 6d41cfe906f97dbed1cea8c9ed06a1f6dc84308e
2024-03-10 20:25:48 +08:00
LinB203 a7165b506e clean script
Former-commit-id: 02c61f63a8539a31516b92f5bb7c2d2e428ca7d7
2024-03-10 18:34:37 +08:00
lb203 740363460f Update README.md
Former-commit-id: 7a62dec060c91b02ca556451266e6f3ef28e03e7
2024-03-10 18:27:50 +08:00
lb203 aeb3081341 Update pyproject.toml
Former-commit-id: 5c379b6e4515ad75b89cdebbc5cd490c9a821d78
2024-03-10 18:21:50 +08:00
lb203 fb62b8ff7e Update README.md
Former-commit-id: 059d9e863958cfd679dbb8d365de6cd933e284fc
2024-03-10 18:20:28 +08:00
lb203 74494966bd Update README.md
Former-commit-id: 87636c1dc2275c4da77c6368a0f4425bea15dc12
2024-03-10 18:15:21 +08:00
LinB203 b57709108a train 1080p video
Former-commit-id: 74625142ef892f9e7fa459b2f98f2f7ae5b36d6a
2024-03-10 18:08:23 +08:00
lb203 1f4d4cbdfd Merge pull request #112 from sennnnn/diffusion_deepspeed_fix
🐛 [BUG] Add base config for Latte

Former-commit-id: 825aa78ded6a5436d53d488b2c2250ac41b2bff9
2024-03-10 15:29:50 +08:00
sennnnn 995454b518 Add base config.
Former-commit-id: d37c551a0421d6b73dee26060b517c46d8217e4f
2024-03-10 15:24:40 +08:00
lb203 3d3ea0c818 Update README.md
Former-commit-id: 582070d4f97c4a4398dcb9a6699f4ab6e980c812
2024-03-10 15:17:18 +08:00
LinB203 6dae0b1c0c deepspeed
Former-commit-id: 6179a4b0e7d06caed4201a27679abc64615febe6
2024-03-10 15:08:12 +08:00
lb203 557b062028 Merge pull request #110 from sennnnn/diffusion_deepspeed
⭐[Feature] Support deepspeed for latte training.

Former-commit-id: 59e731cb98915a2635547cad904ced7d9fcf73f4
2024-03-10 14:48:03 +08:00
sennnnn 28b7fc4bae Fix typos.
Former-commit-id: c10330d373466f3c1ab455bfb391569b9175bc3a
2024-03-10 13:17:44 +08:00
sennnnn 61f9c5bced Add some comments.
Former-commit-id: d5b5bd7743edde6a63dc74457bded0f8c56be1c2
2024-03-10 12:23:42 +08:00
sennnnn f3274235d8 Support deepspeed zero2 and zero2_offload for latte training.
Former-commit-id: c87e95dd357e6fa6d6fb2dcfee781bc49c039e13
2024-03-10 11:27:33 +08:00
sennnnn 81c455e878 Refactor latte.
Former-commit-id: 7408fd0ee16247afc3d4ba43b8c8e7dfb1091a97
2024-03-10 11:25:56 +08:00
sennnnn 443bab1364 Refactor latte.
Former-commit-id: 304534269f105578097bc16ab497636ad59fd9b2
2024-03-10 11:25:50 +08:00
sennnnn bfe4f15694 Fix mixed_precision bugs of latte.
Former-commit-id: d70a551972e04d95444d46cdbe2bfb16ad099fcb
2024-03-10 11:25:07 +08:00
sennnnn ee3810a585 Decouple mixed_precision and gradient_accumulation to command args.
Former-commit-id: 903d473d1432eb492a87efe184d03439f643b92d
2024-03-10 11:24:39 +08:00
lb203 d6d54da131 typo
Former-commit-id: 9e87366e906ed19726c8905afb27b5df4d4e1512
2024-03-10 11:15:14 +08:00
LinB203 f034826c6d fixed attn_mask in flash-attn
Former-commit-id: 5e2504f429a342b75bc7a9004cee7b3f75582ee3
2024-03-10 11:12:12 +08:00
lb203 74ee558f49 Merge pull request #107 from jpthu17/fix_2d_RoPE_init_bug
[fix] 2d RoPE init

Former-commit-id: e873ffa66f01268cce600f8da9ad297dc3e8aaaf
2024-03-10 10:21:43 +08:00
jpthu17 75938cfaeb [fix] 2d RoPE init
Former-commit-id: ff5931bae6efa94675b9ef6bc25f1b76217d128e
2024-03-09 22:04:15 +08:00
LinB203 9a0d0bc843 safe dit
Former-commit-id: f407cab7dc0e53257972d430e873f4fd77bb039d
2024-03-09 21:53:43 +08:00
LinB203 5ebb382d85 xformers and flashattn
Former-commit-id: 002cad95253f7da36344237ce8c8410ffb517711
2024-03-09 21:52:03 +08:00
lb203 c08f985c8c Update README.md
Former-commit-id: 6630c22baa2340a8b55badd61472daab7177bc63
2024-03-09 21:19:47 +08:00
lb203 c891f85022 Merge pull request #106 from jpthu17/add_2d_RoPE
[feat] Add 2D RoPE

Former-commit-id: 85c46fa0e728c9cfc5af4cf6523a7e6a64f96a93
2024-03-09 21:18:17 +08:00
lb203 ad54bd8f94 Merge pull request #105 from sennnnn/einops_bug
Fix einops bug: module 'keras.backend' has no attribute 'is_tensor'

Former-commit-id: c4f3a3a1172b68a4a34ddfac8ea69be34d11038b
2024-03-09 21:13:29 +08:00
jpthu17 aef95b043c [feat] Add 2D RoPE
Former-commit-id: ccae80d339e34fb23706827565b5095ae2c2f320
2024-03-09 19:53:48 +08:00
sennnnn 5834bc0a8b Merge branch 'main' into videogpt_deepspeed
Former-commit-id: 04dbc4c5f04d1e82815e02c6215d8ff6e098049f
2024-03-09 19:24:12 +08:00
sennnnn 29e167fecf Fix einops bug: module 'keras.backend' has no attribute 'is_tensor'
Former-commit-id: 849f8ed815295bac78c3c10d319e6731aa26ca02
2024-03-09 18:18:26 +08:00
sennnnn efad4348d5 Fix config typos.
Former-commit-id: 455973b57bda19379d41e59aa418421fd269281e
2024-03-09 17:39:03 +08:00
sennnnn 3b4e881b11 Support deepspeed for videogpt training.
Former-commit-id: 1f3dfe038845d91b81b0ecc9b6f3cabb06eed5d5
2024-03-09 17:33:30 +08:00
lb203 e415e25897 Update README.md
Former-commit-id: 513883df1ad853c9a5e7457c364227261df17a83
2024-03-09 17:13:18 +08:00
lb203 e2b563ab2d Merge pull request #91 from RuslanPeresy/typecheck
[refactor] add static type checking

Former-commit-id: 969dfa6dedaeb64cf776d977b466b14568cc4b1c
2024-03-09 16:54:19 +08:00
LinB203 6df13b07bb flash-attn train and sample
Former-commit-id: e336565bd5ff2aaf4d0b4ad5f42732e89cd216b3
2024-03-09 16:30:09 +08:00
lb203 39e398e815 Merge pull request #103 from rain305f/new_eval
[docs]: update the eval code

Former-commit-id: 5ee073e7493a608c27c257b2a341585192c5b68f
2024-03-09 15:47:54 +08:00
rain305f e780368bb6 [docs]:update the eval code
Former-commit-id: a8c9e6cb9e39a9e929dab34077280a8d80d85573
2024-03-09 06:22:04 +00:00
rain305f 8a987de2a8 [docs]:update the eval code
Former-commit-id: 937f2fc87d34ab9d4724cb95a6457b54a6bf4ebc
2024-03-09 05:21:43 +00:00
lb203 a60217616e Update README.md
Former-commit-id: 38e0e290e7a5909706c2cce2e4dd047647134fb8
2024-03-09 11:49:17 +08:00
lb203 fa401d1d3f Update README.md
Former-commit-id: 88e9f21cfc8ec775dbc9a65f740043e91e26bd91
2024-03-09 11:44:12 +08:00
lb203 81f5e207d0 Update README.md
Former-commit-id: 826cc5e9162888bed82413088c6be662c278176b
2024-03-09 11:41:37 +08:00
lb203 7774b0d1eb Update pyproject.toml
Former-commit-id: 36da5d0e950625e629aebe954f89f92827397d0d
2024-03-09 11:37:47 +08:00
lb203 82cc72a739 Merge pull request #96 from Jason-fan20/my-docs-branch
Update README.md

Former-commit-id: 426cbdfa78282e098739dc1740d802d8e9c7d6de
2024-03-09 10:58:50 +08:00
lb203 39848c3dff Merge pull request #102 from sennnnn/vqvae_data
🐛 [BUG] Fix the memory error bug when loading metadata pickle file of vqvae dataset

Former-commit-id: 3b458d91fdc646e63f004031ebab9984a34934d2
2024-03-09 10:58:18 +08:00
Li Hao c8ba21979e [BUG]: Shorten the refined caption
Shorten the refined caption using GPT-3.5 summary


Former-commit-id: bb159f0d5fa928258475b2058983397ceb91af9d
2024-03-09 10:22:09 +08:00
lb203 38c2c2ccaf Merge pull request #99 from jialin-zhao/jialin-zhao-xformers-inputs-revised
Update latte.py about the xformers input dims

Former-commit-id: 421b49c351124170ab476e17cba6e45bd7cf706e
2024-03-09 09:58:51 +08:00
lb203 c42a86310d Merge pull request #94 from rain305f/eval_code
[feat]:update the eval_code for calculating the FVD, clip_score etc. metric

Former-commit-id: 363b237f71387e51164d02ed622c5b997fd5dde3
2024-03-09 09:43:25 +08:00
LinB203 b0a9e72008 extract script
Former-commit-id: 4139f2f68ae09695302ce49afdb7318df83cabfd
2024-03-09 01:03:05 +08:00
lb203 7573495d70 Update README.md
Former-commit-id: 99b0066895af072a8887737f2b603ec7fc893ccd
2024-03-09 00:33:09 +08:00
rain305f 130fcd397a [docs]: update the evaluation
Former-commit-id: 02e3789b74daa036fbbff6d13dfc7e98372260ed
2024-03-08 15:38:54 +00:00
sennnnn 41b14c6a13 Fix the memory error bug when loading metadata pickle file of vqvae dataset.
Former-commit-id: 97ab243bd12915cea7aa2deecfac4b99417f78a3
2024-03-08 22:54:17 +08:00
lb203 f751508193 Merge pull request #55 from SimonLeeGit/main
[refactor]: add docker development support

Former-commit-id: 159477551119f68a07adeab349d37083b390e533
2024-03-08 20:51:55 +08:00
lb203 8eef9df1b4 Merge pull request #61 from Mon-ius/main
[feat] - add CI for docker autobuild

Former-commit-id: f9b004a99e67a32be46c1bb3267ad20378b1e89b
2024-03-08 20:50:48 +08:00
lb203 61643ba9e8 Merge pull request #100 from Linzy19/230308
[Updata] updata the video super resolution

Former-commit-id: ebfe0c526f0ee977a91ef0214658783972afc0ac
2024-03-08 20:49:49 +08:00
ZongyingLin 80d857ac86 [Updata] updata the video super resolution
updata the run.py and add README.md


Former-commit-id: 1e6d6ace7a0963149e228813801210b022aceacf
2024-03-08 20:45:47 +08:00
Li Hao 99fe427ac8 [feat]: Caption Refiner
Caption Refiner for Video Caption


Former-commit-id: 97c16bccb9979acf19fb91ae8d7b84ac4a3b4d97
2024-03-08 20:04:41 +08:00
chialin cd2ffd7229 Update latte.py
revise the xformers inputs

Former-commit-id: 60db66c912192c3fbafe55ebe16157514b884e5b
2024-03-08 20:02:31 +08:00
Jasonfan 825fe9eada Update README.md
Former-commit-id: 8f7b41118a3f491d1d5b5789c53790c46b023191
2024-03-08 19:59:51 +08:00
lb203 e3f002e280 Update README.md
Former-commit-id: 70f6ebf421f0830a51dcc2838c2c3783cfb67376
2024-03-08 19:24:44 +08:00
LinB203 a23d24fd11 fix extract feature
Former-commit-id: d4dce5ec1aaa058e452a41f15cd35fe1713f0b78
2024-03-08 19:22:36 +08:00
LinB203 2fd41ff003 update sample.py
Former-commit-id: 10d8621051d1510270c6a55abe686eac86297170
2024-03-08 17:28:16 +08:00
LinB203 bc4e4f6fa6 del use_fp16
Former-commit-id: 5424c0112e04b56d1df30ac76cbc104e848406a3
2024-03-08 17:27:22 +08:00
LinB203 eaee962fa9 update train.py
Former-commit-id: 844173711342f2dcc021294e87971ca39854bfe4
2024-03-08 17:25:48 +08:00
LinB203 b07538bf8a feature dataset
Former-commit-id: 9683caae8648735552270b871de22fc540ba2b55
2024-03-08 17:24:23 +08:00
LinB203 21fad0d34a update script
Former-commit-id: 43f539b68af150c45040d79918a84de1dce47c33
2024-03-08 17:21:06 +08:00
rain305f 77a79e67b6 [docs]:update the eval_code for calculate the FVD, clip_score, ssim, lpips, psnr
Former-commit-id: b504623d7ec2ac0b508530d21ffc88978f8a4f71
2024-03-08 09:19:42 +00:00
rain305f cf2e4f48d0 [docs]:update the eval_code for calculate the FVD, clip_score, ssim, lpips, psnr
Former-commit-id: 1ee226c338126fbdc5178020b12271b980a7ce0c
2024-03-08 09:11:05 +00:00
SimonLee 9c406ca0d7 Merge branch 'main' of https://github.com/PKU-YuanGroup/Open-Sora-Plan
Former-commit-id: aa4a88029885ff0b6e4e96174c07927116150434
2024-03-08 15:44:23 +08:00
RuslanPeresy 7e7dcbe406 [refactor] add static type checking
Former-commit-id: 12c4240dc28888c61f1f79243627e7cdb445c840
2024-03-08 15:37:47 +08:00
SimonLee 9711db6896 update docker scripts and configs
Former-commit-id: 4567e6368f1bf413d8f6319a97a852b8289ca770
2024-03-08 15:32:17 +08:00
lb203 e37dae81ac Delete scripts/train_vqvae.sh
Former-commit-id: 952a4ce3a3b0da159d599ff3a0a052265f48c2dd
2024-03-08 11:21:00 +08:00
lb203 20ca4c089c Update README.md
Former-commit-id: c6b1ea8f1ef01096aa8c3e5272bc9fb255b5532b
2024-03-08 11:18:43 +08:00
SimonLee 518ce56f09 [refactor]: add docker development support
Former-commit-id: fded3baff7915c0cfc9cec3765c271259359831c
2024-03-08 10:58:28 +08:00
lb203 997738438f Update README.md
Former-commit-id: 97fe914aaa2b9bd7c2ff5d4239381631c47e8356
2024-03-08 10:01:16 +08:00
lb203 b76c71e634 Update __init__.py
Former-commit-id: 03a45aaf60d294b7a68d8fc44132d3d671e4472b
2024-03-08 09:46:17 +08:00
Liu Hanchen 203105e504 Update README.md
Former-commit-id: b37da2202e730a4930a194a80a703b591a535adf
2024-03-08 01:27:35 +08:00
Liu Hanchen 76ce11567a Update README.md
Former-commit-id: bca7070fac79d5ae5c37830cd55ca1e81a289197
2024-03-08 01:24:29 +08:00
Liu Hanchen d6980acdd1 Update README.md
Former-commit-id: c4d7aafa3ceb6e4d48bf85b402ae2b2ce9394e53
2024-03-08 01:16:28 +08:00
Liu Hanchen 2448aa7c8c commit
Former-commit-id: 81359cf67248b6c594ff79f121a8a38558c1cc70
2024-03-08 01:04:16 +08:00
lb203 bb167c3a70 Update Data.md
Former-commit-id: 86be6b2bf5a9be1030bb3af661a2ec85e710a5c3
2024-03-07 23:00:54 +08:00
lb203 85232cc966 Update Data.md
Former-commit-id: 9531e33666f842125b331cb266eb26a3a03a4009
2024-03-07 22:35:54 +08:00
lb203 ad5632cc50 Delete opensora/models/super_resolution/placeholder
Former-commit-id: 8dd5a6a3c85dc28989ff95e6ad41be7fdb0f0811
2024-03-07 22:19:00 +08:00
LinB203 9c8b50a29a train script
Former-commit-id: 3fd1ccf099c2deed20af50bf9556e2fc3b7a4382
2024-03-07 22:17:39 +08:00
lb203 68cf1dd673 Merge pull request #88 from Linzy19/2307
[updata] updata video super resolution

Former-commit-id: 7f512b4f186a795358b7e2c922068e2f881aabae
2024-03-07 21:53:22 +08:00
ZongyingLin ae766cb6dd [updata] updata video super resolution
updata video super resolution


Former-commit-id: 82397545859791d112d6f0569e33fe23437563df
2024-03-07 21:27:28 +08:00
lb203 2e84d17e50 Update README.md
Former-commit-id: 7cd398721e556db6199f1d06c7a0d1de2a9720dd
2024-03-07 21:22:24 +08:00
lb203 9f4a42baf9 Update README.md
Former-commit-id: 076e6e70e717888f24265d624c6a7a8ffa2f5d1b
2024-03-07 20:48:32 +08:00
lb203 7a03fe4ccc Update README.md
Former-commit-id: deddba1f03bf697fb1252a0ce4fdb5df5bcae8de
2024-03-07 20:44:55 +08:00
lb203 af8ade6655 Update README.md
Former-commit-id: a1d1f07c83eb0c03d93b023b5c9162a6a3c26cd9
2024-03-07 20:44:12 +08:00
LinB203 af49b2a9e9 init pos embed
Former-commit-id: 28f8076136ec214c66039ead7547c9b25cfe7bfc
2024-03-07 20:01:10 +08:00
lb203 0ca3104739 Update README.md
Former-commit-id: e458366e47d4b13737a71bbf866e20ec10961ade
2024-03-07 19:52:52 +08:00
lb203 781c8ca81d Update README.md
Former-commit-id: 3b4eb14dcd8862b8251b72f30cba523a5dc1def8
2024-03-07 19:52:06 +08:00
lb203 2c7fa77589 Merge pull request #84 from Nyx-177/main
[docs] Modify README.md to fix spelling and grammar issues

Former-commit-id: 096a602e57b5dc3a99d98fc55d608f7569b17af6
2024-03-07 19:42:57 +08:00
Nyx 4cd6d293ca [docs] fix merge conflict
Former-commit-id: d8b1afe957765f3844bd9c1d88dd925efa57330e
2024-03-07 21:30:20 +10:00
Nyx 5149e05147 [docs] Modify README.md to fix other grammatical errors
Former-commit-id: f0de27fcc38bb4dab0eeafac225a2924080a3218
2024-03-07 21:15:56 +10:00
lb203 fbd9b89c01 Update README.md
Former-commit-id: 8a191abc1903ad5998fe83149c9c9ef5c8226b9e
2024-03-07 19:14:49 +08:00
lb203 a0a8e4fb76 Update README.md
Former-commit-id: a881ff5198e1125032418f4f02fd95d2179ffb3a
2024-03-07 19:14:12 +08:00
Nyx d57553d520 [docs] Modify README.md to fix translation error in name "CloseGPT"
Former-commit-id: dd36043df4b0408e592a82f9046f6d654a5375c3
2024-03-07 20:55:02 +10:00
lb203 8e0e8ba91e Update README.md
Former-commit-id: 2a68a1aa399a53f58246df4f9f64dfdcdd130bcf
2024-03-07 18:46:14 +08:00
lb203 28ea2cc1b2 Update README.md
Former-commit-id: 7bc544af55c0a987d0df426848cb06cb330fd52b
2024-03-07 18:16:23 +08:00
lb203 4a07be0b0e Merge pull request #82 from sennnnn/star_his
Rapidly increasing stars are the best honor of a great open-source project.

Former-commit-id: 6aeda408cc64765f00092e61b6ad9a3f0b48fe4d
2024-03-07 17:51:10 +08:00
sennnnn ff69d06080 Fix conflict.
Former-commit-id: 6d4a3950cb135718b3f122657733cb5f890db971
2024-03-07 17:46:31 +08:00
sennnnn 390d7f1896 complement emoji.
Former-commit-id: 50679cc482d8ecf4e3083c0f5a791f195a58a855
2024-03-07 17:39:51 +08:00
lb203 ca9bbce122 Update README.md
Former-commit-id: 7af6b82b29c265e53e9c48477083b4cff0e0a3d3
2024-03-07 17:37:24 +08:00
sennnnn 0fde7b4edd refine readme.
Former-commit-id: 391d9511b72aa9c09c7ad8992ae5df8c89c88c63
2024-03-07 17:37:22 +08:00
lb203 74115d65c4 Update README.md
Former-commit-id: f4c4b3b4b1ce3c1d0b56ba5a109cd6cc57da900d
2024-03-07 17:27:18 +08:00
lb203 a261d31f3a Update README.md
Former-commit-id: 2a286e5aab48aa68e7d3f04df23ec1cdfe71c6de
2024-03-07 17:25:52 +08:00
lb203 da2c84cf50 Update README.md
Former-commit-id: 4a04e71636dabccbef446623674f3a514395b7f9
2024-03-07 17:21:53 +08:00
lb203 3dc3c31fda Update README.md
Former-commit-id: da5507e570a27becab754ba24a0671d669b7e08e
2024-03-07 17:03:17 +08:00
lb203 d14563a9d4 Update README.md
Former-commit-id: 4d83f1feab7d6872aca1c6b41be95950ec3cf465
2024-03-07 17:00:33 +08:00
LinB203 784c246e9c videogpt inference
Former-commit-id: c5d617450a8271ad3b8a5e8f76ee2d77a822e31b
2024-03-07 16:44:19 +08:00
LinB203 11996dc9b4 fixed dit forward
Former-commit-id: 4cd537fab12231f7471107762b02b36217ca42d8
2024-03-07 16:41:31 +08:00
lb203 a03025a8f3 Merge pull request #80 from qqingzheng/videogpt
[docs] Modify README.md and add VQVAE documentation.

Former-commit-id: a92ddf62b7bbd15820401f52edf853dbbb513301
2024-03-07 16:39:28 +08:00
lb203 035214520e Update README.md
Former-commit-id: 89f9fc8eed3ca8cc2434ec227acbb845bfbcff82
2024-03-07 16:37:47 +08:00
lb203 93e98f1ef5 Update README.md
Former-commit-id: 4a893ff6177d59219b6755c4a89764ef54fc7f62
2024-03-07 16:36:16 +08:00
lb203 8b4ad5bf4f Update README.md
Former-commit-id: 0898e4b917f5e245c4394118511bcb7639973817
2024-03-07 16:33:17 +08:00
lb203 afdd297bd5 Update README.md
Former-commit-id: 8b553a4477c64b5452f8424ca6987c0fb8c111ce
2024-03-07 16:31:19 +08:00
lb203 8aa1181ab2 Update README.md
Former-commit-id: 8e9658ed993380abc43b518fcbac21a02d8ba9ba
2024-03-07 16:26:12 +08:00
Chestnut b64293c723 Merge branch 'PKU-YuanGroup:main' into videogpt
Former-commit-id: 339857e1b672a1a688f86c1b8e1d8dae29f10301
2024-03-07 15:03:43 +08:00
qqingzheng d681598e6e [docs] Modify README.md and add VQVAE documentation.
Former-commit-id: a5bfe70f8a8998db969d9c4938fda123aa153bc0
2024-03-07 06:59:40 +00:00
qqingzheng cb86e18190 [refactor] rename train_videogpt.sh
Former-commit-id: e2ea2caacaf5be046f48cf50a53ccafa7a3cc351
2024-03-07 06:15:14 +00:00
lb203 9d9bad199c Merge pull request #76 from luo3300612/dev-rec-video
[fix]: disable gradient computation to save GPU memory when reconstructing a video

Former-commit-id: b8cda6636444080d0cf00452be75a70c1e79f32a
2024-03-07 13:49:39 +08:00
lb203 b6bc9b1455 Update README.md
Former-commit-id: 36e69275598b0cff38fdc5006926e422cda069b3
2024-03-07 13:47:45 +08:00
lb203 5caa97e9a9 Update README.md
Former-commit-id: 4179ed075e68d48094655c38dbde784836fd6e0f
2024-03-07 13:46:58 +08:00
lb203 f507bb4947 Update README.md
Former-commit-id: a1cc0b26a3b156d7708e8df0cfe42aad33b1c946
2024-03-07 13:45:01 +08:00
luo3300612 0379dbb349 [fix]: disable gradient computation to save GPU memory when reconstructing a video
Former-commit-id: 06da17790b53cf593a0c264dda17c76f68d2a541
2024-03-07 13:39:56 +08:00
LinB203 c521999f80 attn_mask with bf16
Former-commit-id: d9667a8c15a5344e3c777197fd6badec15dcddbd
2024-03-07 13:35:01 +08:00
lb203 fcc8009570 Merge pull request #64 from khan-yin/main
[feat]: add sit model

Former-commit-id: acacfd670282b709e6c769717b5295e230861724
2024-03-07 13:29:24 +08:00
lb203 5a7e9c8822 Update README.md
Former-commit-id: 29f24a819fe2d4593c48afe6ca990659784bd776
2024-03-07 12:58:47 +08:00
khan-yin c716b3281e feat: update sample
Former-commit-id: e7dc492b9b4764db28aa31cc1eede914052b4ca6
2024-03-07 04:13:57 +00:00
khan-yin 94b71a5ea0 Merge remote-tracking branch 'upstream/main' into main
Former-commit-id: 7ef9b5e76a91b444f87955c3e0e7ea3d72315396
2024-03-07 04:05:06 +00:00
khan-yin e90373b161 feat: Incorporating SiT sample
Former-commit-id: 91e2931e412f8c96ef748cb2322ee956309fb6aa
2024-03-07 03:40:24 +00:00
lb203 7cf1bcc93d Update README.md
Former-commit-id: b3f6bb7f252505efb0ffd8195003c79206fac313
2024-03-07 11:38:23 +08:00
LinB203 cca84f1c6c denorm fun
Former-commit-id: 05707a07b14295f5e1932d0c10bb84a20a0cd328
2024-03-07 10:40:06 +08:00
lb203 1ebf531e1e Update README.md
Former-commit-id: 1a7178a61547c33a744d032302fb76ee0a3c6671
2024-03-07 10:33:20 +08:00
lb203 c9adc3e9a5 Update README.md
Former-commit-id: d097e40998a3396f74c2bfbcf26d6ace8080d0b6
2024-03-07 10:20:51 +08:00
Kehan Yin 3f19169f55 Merge branch 'PKU-YuanGroup:main' into main
Former-commit-id: a2dea6886ce90634fb7d1c2e0fbfce95a500eefc
2024-03-07 10:04:08 +08:00
lb203 006ad5353a Merge pull request #70 from qqingzheng/videogpt
[refactor] Performed code abstraction on the VideoGPT code and enabled support for accelerate training.

Former-commit-id: 822c1a173f5bc792868fae9e6e4cd7defe2ea183
2024-03-07 09:23:28 +08:00
Chestnut 589da07fec Merge branch 'main' into videogpt
Former-commit-id: 714cc434cea5823fc09ef6fe502b1fe83170cae2
2024-03-07 01:25:58 +08:00
qqingzheng b409ef399a [refactor] added more methods in abstract classes
Former-commit-id: a535e3a06eb766bebe7baa3d9df64b04d04d40e6
2024-03-06 17:23:40 +00:00
lb203 8944956249 Update README.md
Former-commit-id: 604a29d1de43e0fcb90ada4dd97f5f080e37caea
2024-03-07 01:11:28 +08:00
lb203 921d927a27 Update train.sh
Former-commit-id: 66aa3709f80d89a30d0a57c5e033ce1ae46f998f
2024-03-07 01:06:20 +08:00
lb203 06423d785d Update train.sh
Former-commit-id: 6c4957d715eaa489691be21dd0abdb9309660e0d
2024-03-07 00:57:14 +08:00
LinB203 38bf4afdfa support accelerate training
Former-commit-id: b32671c9991b9a9db66cb148822ccb3e8be7dc11
2024-03-07 00:55:35 +08:00
qqingzheng 7a78ef2a97 [refactor] configuration default values
Former-commit-id: d7ca7685d6a8c6d015082dda241bc98ab156770d
2024-03-06 15:59:13 +00:00
qqingzheng 4549eeeab3 Merge branch 'videogpt' of github.com:qqingzheng/Open-Sora-Plan into videogpt
Former-commit-id: ca5f92952c7a0daae6deaca40f6dab1d00a0c0b2
2024-03-06 15:48:26 +00:00
qqingzheng da08e767db [refactor] rename
Former-commit-id: ec317605d24223527b8c2d4b4d2ee876f86abbaf
2024-03-06 15:48:19 +00:00
lb203 0118dd8f1d Merge pull request #69 from luo3300612/dev-rec-video
[fix]: disable gradient computation to save GPU memory when reconstructing a video

Former-commit-id: f9afcda4130e1709d6f201ed310adcc8335480d9
2024-03-06 23:46:10 +08:00
lb203 4efdbc2aca Update README.md
Former-commit-id: 59a595a1e31b156500a944f244afec40988e872d
2024-03-06 23:39:17 +08:00
Chestnut 140eb267d9 Merge branch 'main' into videogpt
Former-commit-id: 0a45d76fdcc3faf167239dfe5dc055b30f3f4e05
2024-03-06 23:36:14 +08:00
LinB203 1b99cf2789 add sample script
Former-commit-id: 9ce847651bb6dba28c51ce5807e222ae2902a78a
2024-03-06 23:23:17 +08:00
lb203 ae2646e213 Merge pull request #74 from Linzy19/2307
[update]: update super_resolution

Former-commit-id: a2586e672bd5d60f1a5e937a796d5f6b6ac1da4d
2024-03-06 23:19:44 +08:00
ZongyingLin 36e0f8813a update
add RGT


Former-commit-id: a491111e48cec588095381eb70ffca94600ca4f7
2024-03-06 23:10:26 +08:00
qqingzheng 0622ea11dc [fix] fix a bug when using ucf101_stride4x4x4
Former-commit-id: f541e723d65ea44ae4560c68908123c7e6781bbc
2024-03-06 15:08:36 +00:00
qqingzheng df625f66cc [refactor] remove test.ipynb
Former-commit-id: e73c3a9e0d41e51a0fd755e57739424213a76312
2024-03-06 15:07:11 +00:00
qqingzheng 107f140b56 [fix] fix a bug when using ucf101_stride4x4x4
Former-commit-id: 9911403c688321db731450d9383bc02923a4be2d
2024-03-06 14:51:35 +00:00
Chestnut 2fd71909a4 Merge branch 'main' into videogpt
Former-commit-id: f8de10e627ce27f1511ddbbc5d6b29f3daf094ab
2024-03-06 22:13:26 +08:00
qqingzheng 2b272863b0 [refactor] adapt to old training code
Former-commit-id: 358d362ecbc100b21ea02895cb0426cf5b386a72
2024-03-06 13:58:13 +00:00
qqingzheng 1bed11aee3 [refactor] reformat videogpt, support training videogpt on accelerate
Former-commit-id: 75385ed47fe60008b61b1bcf89f61ea696d095bc
2024-03-06 13:45:16 +00:00
lb203 5dc0b3cb41 Update README.md
Former-commit-id: 673659495b7503ba402fbcb6c46204499761b4cf
2024-03-06 21:24:58 +08:00
root 80d394d64a [fix]: disable gradient computation to save GPU memory when reconstructing a video
Former-commit-id: b7bf763e7f8800959ed82bb89f41684db216dd8e
2024-03-06 21:04:29 +08:00
lb203 f58d14ba24 Update README.md
Former-commit-id: 398cfcd7b19cf1ba827eb49fc11223f72fa93a85
2024-03-06 20:46:10 +08:00
lb203 d3acf63c4e Update README.md
Former-commit-id: 9fd88eb8ac5122b0999ccb0071f195aaeb0979a0
2024-03-06 20:30:57 +08:00
LinB203 193d7ef7a0 support latte training
Former-commit-id: d471a9414842f422d1200c2fd3f3ddfcf9e97fd6
2024-03-06 20:29:31 +08:00
khan-yin e47f894f69 fix: rename sit model filename
Former-commit-id: f3b2cd7dcf644f680616eee0571db90478fede23
2024-03-06 12:08:04 +00:00
khan-yin 7cee5443e4 fix: remove replicated diffusion module in sit
Former-commit-id: 997cb049185421d303b14d59ab6c0603f1d1a66f
2024-03-06 12:06:55 +00:00
Kehan Yin edfe14e9fa Merge branch 'PKU-YuanGroup:main' into main
Former-commit-id: c7d4f9c2cfaa61e3babc711f13a095ed237978b1
2024-03-06 19:46:26 +08:00
lb203 31f5ce25d4 Update README.md
Former-commit-id: 898d35f15ce0fd124cd48078f0a8af2764bf55d1
2024-03-06 19:33:06 +08:00
LinB203 5a80da7ec1 add vae and fix bug in dit
Former-commit-id: 2dd4254c22ce671d5cd5e7d22a2386b7660fbdc4
2024-03-06 19:32:20 +08:00
lb203 ec0dd141e1 Merge pull request #63 from kabachuha/alternative-attentions
Support for less VRAM heavy alternative attentions (ReBased and Ring attention)

Former-commit-id: c90f9d3c780843edccc72d29f68f5ed7c655a721
2024-03-06 19:28:59 +08:00
khan-yin 54d3069702 [feat]: add sit model
Former-commit-id: 2eda854d6c25254b71d0105a3ed092953a9d6f68
2024-03-06 09:52:27 +00:00
kabachuha abffb358f9 support for ring attention
Former-commit-id: 0533c73b99217e88da121bd0f68e0949bc88016e
2024-03-06 12:24:10 +03:00
kabachuha e1459ff3d0 option to use rebased linear attention
Former-commit-id: f1b39b34df5fbdef14ef3f6a0e6d0972a8570445
2024-03-06 12:18:03 +03:00
Monius f2a826a2f8 add CI for docker autobuild
Former-commit-id: c4e2d5ff1dce8662a42f1ed6a7786855d40173f7
2024-03-06 16:58:03 +08:00
lb203 29409555f3 Update README.md
Former-commit-id: 10ee64c122f28efea39fc1a4542d278683a58ce1
2024-03-06 16:27:06 +08:00
lb203 d878709456 Update README.md
Former-commit-id: 0f2bdd2bcd819d528f2a41a96ba93f5c3c04dc8c
2024-03-06 16:23:53 +08:00
qqingzheng 3810227fd6 first commit
Former-commit-id: ec3481bc35a8120d519082dc76585428f0896470
2024-03-06 08:16:58 +00:00
lb203 8b3920706a Update README.md
Former-commit-id: f1aaeca19bc9e4304961c8c903f9bf03cb42fd9f
2024-03-06 16:13:26 +08:00
lb203 932c7fd80b Create LICENSE
Former-commit-id: 369fe085e91e55b9be6165da4a1eb7f9c0cf5a7f
2024-03-06 16:12:41 +08:00
lb203 cfb34d011b Delete LICENSE.txt
Former-commit-id: b10d8b2c6620e3a8412527bd03ea0adc26c981a6
2024-03-06 16:11:05 +08:00
lb203 0147265637 Update README.md
Former-commit-id: 437bc5c68b5c7a85865ad97d544c4818be45cb52
2024-03-06 15:38:04 +08:00
LinB203 cf40ce1e7a add latte
Former-commit-id: 01ba10e5d65c9d2d957472fbe7958e1b07a971e9
2024-03-06 15:28:20 +08:00
yanyang1024 4f608035e2 Update README.md
Former-commit-id: c5a79c7e993d9e6a77c6c70efa1c0ac2bb3a063b
2024-03-06 12:12:58 +08:00
yanyang1024 70ee26f0ec fix_readme_requirements
Former-commit-id: eb5a5c69d12cc412c12a4fea7f00baafd02701ca
2024-03-06 12:05:21 +08:00
lb203 e14c09b3da Update README.md
Former-commit-id: 1436d8feea7f82d3d747c632a68c47b3ea74258f
2024-03-05 22:11:38 +08:00
lb203 3ecbc2eab6 Merge pull request #50 from yunyangge/interpolation
[feat]: frame_interpolation

Former-commit-id: 59ac3fd0b48bcd89f2b1f816b74a4e17c83328b2
2024-03-05 22:10:18 +08:00
yunyangge 21b257c25e [feat]: frame_interpolation
Former-commit-id: 711fc4bba80d5f051f712e3460e2c0685117cf68
2024-03-05 21:53:22 +08:00
lb203 458d1d7770 Update README.md
Former-commit-id: 3e3d674134498512b1ef1b0dd72d6e19afd6ef65
2024-03-05 15:52:05 +08:00
lb203 34c1d8d2d0 Update README.md
Former-commit-id: 164e76cf496b1157eebea299ed58ca6c1799d70d
2024-03-05 15:50:45 +08:00
lb203 192abaeb9e Update README.md
Former-commit-id: be7ecc3d56f7289052fc66d535038e7111f7ac84
2024-03-05 15:46:32 +08:00
lb203 8b2f93325f Update Contribution_Guidelines.md
Former-commit-id: dc87e459ca5a8a090800331111118acb65214f65
2024-03-05 15:01:08 +08:00
lb203 2ca658809a Update README.md
Former-commit-id: 6ecaba8e03d7c7f99c068a57c923f11c5456a8c9
2024-03-05 14:54:38 +08:00
lb203 86332d9c0a Update README.md
Former-commit-id: 1dd9c945be2a170d87d568bb00e1ec30e7be592b
2024-03-05 13:46:09 +08:00
lb203 f26658b7de Merge pull request #42 from mio2333/patch-2
Update requirements.txt

Former-commit-id: 0c76835e4a4681ee317de45a18549dc0d9b9fef9
2024-03-05 13:39:23 +08:00
Junwu Zhang 5a56c37298 reformat code
Former-commit-id: ce23b280fbb419c08347ebcbf1ed4075bdf9af60
2024-03-05 05:38:23 +00:00
Junwu Zhang e01856047d Update README.md
Former-commit-id: 351be764d8648ac60cf170c3fe4e6ed9c544c90e
2024-03-05 13:34:35 +08:00
Junwu Zhang c14ef52685 Rename data.md to Data.md
Former-commit-id: 27484f7a2d8634bd1cd9781a2f10afa7f304f5cb
2024-03-05 13:31:50 +08:00
Junwu Zhang c62e40c802 Update README.md
Former-commit-id: c652acd1fc5a003b4d6eefcfb83dfb310f5b5e81
2024-03-05 13:31:23 +08:00
Junwu Zhang 370be675e8 Create Contribution_Guidelines.md
Former-commit-id: 897dbd63dc6f53095e1dda3f10a86dd40e4bd263
2024-03-05 13:28:32 +08:00
mio e72ef94a7f Update requirements.txt
As in previous step,the three packages have been installed, these packages should be deleted here because it can not be installed by " pip install -r requirements.txt" command and will abort the command

Former-commit-id: 0655fa28cf8bb761f1a3d2def62f44197b257b2c
2024-03-05 13:22:28 +08:00
Junwu Zhang e777c2e617 Update README.md
Former-commit-id: f295f4623448dd4ffa9be747a5cc6733cf48c663
2024-03-05 12:51:07 +08:00
Zhenyu Tang e4eee7bc20 Update README.md
Former-commit-id: 0ff9314bddef1dfbbf429726ed4240b823b221b3
2024-03-04 22:45:06 +08:00
Zhenyu Tang b2dbc2099e Update README.md
Former-commit-id: e27cc5d49a19e9580ba1a29d948051b918aede74
2024-03-04 22:41:37 +08:00
YuanLi 24006388be Update README.md
Former-commit-id: 1cd7d8b5df34ab9f61d9346b2647b643f78a8f5d
2024-03-04 22:41:04 +08:00
Zhenyu Tang cf5bafaee6 Update README.md
Former-commit-id: 5fd1e6afe1277ccffdfeaf507477d944a6a35f03
2024-03-04 22:28:08 +08:00
Zhenyu Tang 028c52fd9f Update README.md
Former-commit-id: fb46c80c1a2663c09849472e93b2da6cd068a98c
2024-03-04 22:24:21 +08:00
Zhenyu Tang b7dfe57c17 Update README.md
Former-commit-id: aee63a3a8422e029f1550e47825ca4beb916874b
2024-03-04 22:23:44 +08:00
Junwu Zhang a02832797a reformat code
Former-commit-id: 7a3dccf2c738eaf535e62996211c8bc5f3de5683
2024-03-04 14:06:39 +00:00
1324 changed files with 11555 additions and 234471 deletions
-46
View File
@@ -1,46 +0,0 @@
# Exploration Logs
This directory holds draft procedures and investigation notes for tasks that
don't yet have a standardized skill or SOP. Each exploration should follow this
template.
## When to Create an Exploration Log
- You are working on a task with no existing skill or workflow.
- You are experimenting with a new metric, training technique, or tool.
- You want to document findings before they are promoted to a standard.
## File Naming
`<topic-slug>.md` — e.g., `fvd-metric-investigation.md`
## Template
```markdown
# Exploration Log: <Topic>
## Status: draft | under_review | promoted | abandoned
## Context
<Why this exploration is needed — link to experiment or task if applicable.>
## Progress
- [ ] Step 1: ...
- [ ] Step 2: ...
## Findings
<What you have learned so far.>
## Mistakes / Dead Ends
<What didn't work and why — these become lessons.>
## Proposed Standardization
<If this works, describe the skill/SOP/workflow to create.>
```
## Lifecycle
1. **Create** during exploration mode.
2. **Update** as you make progress.
3. **Promote**: If findings are solid, create a skill in `.agents/skills/` or an SOP in `.agents/workflows/`.
4. **Archive mistakes**: Move failures into `.agents/lessons/`.
-48
View File
@@ -1,48 +0,0 @@
# Lessons Learned Database
This directory stores documented mistakes, unexpected behaviors, and their fixes.
Each lesson is a permanent record that helps agents and humans avoid repeating
past errors.
## When to Create a Lesson
- An experiment failed for a non-obvious reason.
- A configuration or hyperparameter choice led to wasted compute.
- A porting, data, or infrastructure issue was discovered and resolved.
- A workaround was needed for a known framework/library bug.
## File Naming
`<YYYY-MM-DD>_<short-slug>.md` — e.g., `2026-03-02_lr-too-high-for-lora.md`
## Template
```markdown
---
date: <ISO-8601>
experiment: <reference to experiment_journal.md entry, if applicable>
category: hyperparameter | data | infrastructure | evaluation | porting | other
severity: critical | important | minor
---
# <Short Descriptive Title>
## What Happened
<Description of the problem and its symptoms.>
## Root Cause
<Analysis of why it happened.>
## Fix / Workaround
<What resolved the issue.>
## Prevention
<How to avoid this in the future — updated skills, SOPs, or checks.>
```
## Usage
- Before starting a task, **search this directory** for relevant lessons.
- After completing or failing a task, **check if a new lesson should be created**.
- Periodically review lessons for **patterns** — recurring themes may warrant
a new skill, SOP, or codebase fix.
-129
View File
@@ -1,129 +0,0 @@
# FastVideo-WorldModel — Codebase Map
High-level structural index for agent orientation. Updated 2026-03-08.
## Repository Layout
```
FastVideo-WorldModel/
├── fastvideo/ # Core Python package
│ ├── models/ # Model implementations
│ │ ├── dits/ # DiT transformers (wanvideo, ltx2, ...)
│ │ ├── vaes/ # VAE models
│ │ ├── encoders/ # Text/image encoders (T5, CLIP)
│ │ ├── schedulers/ # Noise schedulers
│ │ ├── upsamplers/ # Super-resolution models
│ │ ├── audio/ # Audio models
│ │ └── loader/ # Component loaders for HF repos
│ ├── configs/ # Configuration system
│ │ ├── models/ # Arch configs + param_names_mapping
│ │ ├── pipelines/ # Pipeline wiring
│ │ └── sample/ # Default sampling parameters
│ ├── pipelines/ # End-to-end pipelines
│ │ ├── basic/ # Per-model pipelines (wan/, ltx2/, ...)
│ │ └── stages/ # Reusable pipeline stages
│ ├── train/ # Refactored training framework (YAML-driven, preferred)
│ │ ├── trainer.py # Main training loop coordinator
│ │ ├── entrypoint/ # Training entrypoint (train.py) + checkpoint conversion
│ │ ├── methods/ # Training algorithms (FineTune, DFSFT, DMD2, SelfForcing)
│ │ │ ├── base.py # TrainingMethod ABC
│ │ │ ├── fine_tuning/ # FineTuneMethod, DiffusionForcingSFTMethod
│ │ │ └── distribution_matching/ # DMD2Method, SelfForcingMethod
│ │ ├── models/ # Per-role model wrappers (ModelBase, CausalModelBase)
│ │ │ └── wan/ # WanModel, WanCausalModel
│ │ ├── callbacks/ # Composable hooks (grad_clip, ema, validation)
│ │ └── utils/ # Config, builder, checkpoint, optimizer, tracking
│ ├── training/ # Legacy training infrastructure (being phased out)
│ │ ├── trackers.py # W&B tracker (BaseTracker → WandbTracker)
│ │ ├── training_utils.py # Checkpointing, grad clipping, state dicts
│ │ ├── training_pipeline.py # Base training pipeline
│ │ ├── wan_training_pipeline.py # Wan T2V training
│ │ ├── wan_i2v_training_pipeline.py # Wan I2V training
│ │ ├── distillation_pipeline.py # Distillation base
│ │ ├── wan_distillation_pipeline.py # Wan distillation
│ │ ├── self_forcing_distillation_pipeline.py # Self-forcing distill
│ │ ├── ltx2_training_pipeline.py # LTX-2 training
│ │ └── matrixgame_training_pipeline.py # MatrixGame training
│ ├── attention/ # Attention backends
│ ├── distributed/ # Sequence/tensor parallel utilities
│ ├── layers/ # Tensor-parallel layers
│ ├── tests/ # Package-level tests
│ │ ├── training/ # Training regression tests (W&B summary comparison)
│ │ ├── ssim/ # SSIM visual regression tests
│ │ ├── encoders/ # Encoder parity tests
│ │ └── modal/ # Modal CI test runner
│ └── registry.py # Unified config registry
├── fastvideo-kernel/ # CUDA/custom kernels (separate build: ./build.sh)
├── scripts/ # Utility scripts
│ ├── distill/ # Distillation launch scripts
│ ├── inference/ # Inference scripts
│ ├── checkpoint_conversion/ # Weight conversion tools
│ ├── finetune/ # Finetune scripts
│ └── preprocess/ # Data preprocessing
├── examples/ # Ready-to-run examples
│ ├── training/ # Training examples (finetune/, consistency_finetune/)
│ ├── distill/ # Distillation examples
│ ├── inference/ # Inference examples
│ └── dataset/ # Dataset examples
├── docs/ # MkDocs documentation source
│ ├── design/overview.md # Architecture overview
│ ├── training/ # Training guides
│ └── contributing/ # Contributor guides + coding_agents.md
├── tests/ # Top-level tests (local_tests/)
├── AGENTS.md # Agent coding guidelines
└── .agents/ # Agent infrastructure (you are here)
```
## Key Training Entrypoints
### New framework (`fastvideo/train/`) — preferred
| Method | Config Example | Launch Pattern |
|--------|---------------|----------------|
| FineTune (Wan) | `examples/train/finetune_wan2.1_t2v_1.3B_vsa_*.yaml` | `torchrun -m fastvideo.train.entrypoint.train --config <yaml>` |
| DFSFT (Wan causal) | `examples/train/dfsft_wan_causal_t2v_1.3B.yaml` | `torchrun -m fastvideo.train.entrypoint.train --config <yaml>` |
| DMD2 distillation | `examples/train/distill_wan2.1_t2v_1.3B_dmd2.yaml` | `torchrun -m fastvideo.train.entrypoint.train --config <yaml>` |
| Self-Forcing | `examples/train/self_forcing_wan_causal_t2v_1.3B.yaml` | `torchrun -m fastvideo.train.entrypoint.train --config <yaml>` |
### Legacy pipelines (`fastvideo/training/`) — being phased out
| Pipeline | Entrypoint | Launch Pattern |
|----------|-----------|----------------|
| Wan T2V finetune | `fastvideo/training/wan_training_pipeline.py` | `torchrun --nproc_per_node N` |
| Wan I2V finetune | `fastvideo/training/wan_i2v_training_pipeline.py` | `torchrun --nproc_per_node N` |
| Wan distillation (DMD) | `fastvideo/training/wan_distillation_pipeline.py` | `torchrun --nproc_per_node N` |
| Self-forcing distill | `fastvideo/training/wan_self_forcing_distillation_pipeline.py` | `torchrun --nproc_per_node N` |
| LTX-2 finetune | `fastvideo/training/ltx2_training_pipeline.py` | `torchrun --nproc_per_node N` |
| MatrixGame | `fastvideo/training/matrixgame_training_pipeline.py` | `torchrun --nproc_per_node N` |
## W&B Integration
- **Tracker classes**: `fastvideo/training/trackers.py`
- `WandbTracker` — logs metrics, videos, timing
- `SequentialTracker` — fan-out to multiple trackers
- `DummyTracker` — no-op for offline/test
- **Run summary location**: `<output_dir>/tracker/wandb/latest-run/files/wandb-summary.json`
- **Reference summaries**: `fastvideo/tests/training/*/` (e.g., `a40_reference_wandb_summary.json`)
- **Environment**: `WANDB_API_KEY`, `WANDB_BASE_URL`, `WANDB_MODE`
## Critical Environment Variables
| Variable | Purpose |
|----------|---------|
| `WANDB_API_KEY` | W&B authentication |
| `WANDB_MODE` | `online` / `offline` |
| `FASTVIDEO_ATTENTION_BACKEND` | `FLASH_ATTN` / `TORCH_SDPA` |
| `TOKENIZERS_PARALLELISM` | Set `false` to avoid fork warnings |
| `HF_HOME` | HuggingFace cache directory |
## Build & Test Commands
```bash
uv pip install -e ".[dev]" # Editable install
pre-commit run --all-files # Lint/format/spell
pytest tests/ # Top-level tests
pytest fastvideo/tests/ -v # Package tests
pytest fastvideo/tests/training/Vanilla -srP # Training loss regression
pytest fastvideo/tests/ssim/ -vs # SSIM visual regression
cd fastvideo-kernel && ./build.sh # Build kernels
```
@@ -1,163 +0,0 @@
# Dreamverse Integration — Memory Index
Living knowledge base for the FastVideo ↔ Dreamverse ↔ Dynamo integration.
Tracks the public API refactor (PRs 0-17), the LTX-2 streaming server
upstream, the Dreamverse switch from `FastVideo-internal` to public
`FastVideo`, and the NVFP4 quantization landing.
**Last reconciled:** 2026-05-05 (**D-18**: Option B+ chosen — Dreamverse
becomes `apps/dreamverse/` subfolder under FastVideo; generic backend stays
at `fastvideo.entrypoints.streaming.*`. See [integration-plan.md](integration-plan.md)
for the executable 7-phase migration plan;
[integration-review.md](integration-review.md) is **deprecated** but kept
for the drift audit and OSS precedent citations.).
FastVideo `will/ltx2_sr_port` @ HEAD (post-D-17 STACK.md removal +
integration-review.md addition + integration-plan.md addition + D-18
reconciliation). Dreamverse `will/integrate-public-fastvideo` @ `ec8ef92`.
PRs #1257 / #1258 / #1284 / #1286 MERGED to main. **PR #1287 CLOSED
(in favor of consolidation); PR #1288 OPEN as the single mega-PR
landing the entire `will/ltx2_sr_port` chain at once** (LTX-2 SR
runtime + NVFP4 + `generate_async`/Dynamo contract + agents memory dir).
Split branches kept as historical bookmarks; STACK.md model **abandoned** —
see [decisions-log.md D-17](decisions-log.md#d-17). Local backup
`will/ltx2_sr_port-pre-1286-rebase` @ `1baa60bb` preserves the
pre-rebase chain.
## Fresh-context onboarding (read in order)
If you're an agent picking up this work for the first time, do these
**5 things in this order**. Once done, you have full context to continue
any open thread, commit correctly, push, and propagate to the open PR.
1. **Confirm worktree state** — run the "First 60 seconds" block in
[runbook.md](runbook.md). Tells you the branch is right, services
are up, and PR #1286's head matches what this dir claims.
2. **Read [state.md](state.md)** — single-page snapshot of branch tips,
live services, test status, pre-existing failures, "do not pop"
stashes.
3. **Read [pr-roadmap.md](pr-roadmap.md)** — what PRs landed, what's in
flight, what's planned. Identifies the active open PR (currently
#1286) and where it sits in the dependency chain.
4. **Read [open-threads.md](open-threads.md)** — prioritized work items
with effort estimates and dependencies. The "Recommended pull order"
section is a ready-made TODO list if you need one.
5. **Skim [runbook.md](runbook.md) end-to-end** — operational how-to:
verify, commit (with co-author trailers), push, propagate to PR
#1286, maintain the memory dir, and the "Common pitfalls" section
that catches the recurring traps.
Skip the deep-context docs (design / streaming-server / cross-repo /
quantization / decisions-log) until you need them — they're indexed in
the "Deep-dive reading guide" below.
Final check: run the "Self-test" block at the bottom of
[runbook.md](runbook.md). If you can answer all 8 questions from this
dir alone, you're ready. If you can't, the gap is a memory-dir bug —
file it in [open-threads.md](open-threads.md) before continuing.
## Deep-dive reading guide
| Question / task | File |
|---|---|
| "What's running right now? What just landed?" | [state.md](state.md) |
| "How do I commit / push / propagate to PR #1286?" | [runbook.md](runbook.md) |
| "Why is the schema typed this way? What's the philosophy?" | [design.md](design.md) |
| "What PRs landed? In flight? Planned?" | [pr-roadmap.md](pr-roadmap.md) |
| "Streaming server, `generate_async`, `build_app` routes?" | [streaming-server.md](streaming-server.md) |
| "How does Dreamverse use FastVideo? What about Dynamo?" | [cross-repo-surfaces.md](cross-repo-surfaces.md) |
| "NVFP4? Layer profiles? `LinearBase` fallback? AbsMaxFP8?" | [quantization.md](quantization.md) |
| "Why was decision X made? What's resolved vs. open?" | [decisions-log.md](decisions-log.md) |
| "What should I work on next? Priority order?" | [open-threads.md](open-threads.md) |
| "Who should be co-authored on commits in this scope?" | [authors.md](authors.md) |
| "How do we execute the Dreamverse → FastVideo monorepo merge?" | [integration-plan.md](integration-plan.md) ← **CURRENT** |
| "Historical drift audit + Option-D evaluation (deprecated by D-18)" | [integration-review.md](integration-review.md) (DEPRECATED) |
## Repo + worktree paths
| Repo | Path | Active branch |
|---|---|---|
| FastVideo (public) | `/home/william5lin/FastVideo` | `will/ltx2_sr_port` |
| Dreamverse | `/home/william5lin/Dreamverse` | `will/integrate-public-fastvideo` |
| FastVideo-internal (read-only ref) | `/home/william5lin/FastVideo-internal` | their `main` |
| Dynamo (read-only ref) | `/home/william5lin/dynamo` | upstream |
## Glossary
- **NVFP4**: NVIDIA's specific block-scaled FP4 (e2m1 mantissa, fp32 alpha,
`layout_128x4` scale layout, group size 16). Distinct from MX-FP4 / OCP-FP4.
- **`GeneratorConfig`**: typed init-time public config (model_path, engine,
pipeline). Replaces flat `from_pretrained(**kwargs)`.
- **`GenerationRequest`**: typed per-call request (prompt, inputs, sampling,
runtime, output, stage_overrides, state, plan, extensions). Replaces flat
`generate_video(**kwargs)`.
- **`ServeConfig`** / **`RunConfig`**: top-level YAML envelopes. ServeConfig
for `fastvideo serve`; RunConfig for offline `fastvideo generate`.
- **`InferencePreset`**: model-owned named preset (e.g. `ltx2_two_stage`)
defining stage topology + per-stage defaults + valid override types.
- **`ContinuationState`**: opaque round-trip state envelope `{kind, payload}`.
Hybrid: server-held for streaming WS, client-round-trip for stateless HTTP.
- **`generate_async`**: future canonical async exec API (PR 7.10) yielding
`VideoProgressEvent` / `VideoPartialEvent` / `VideoFinalEvent`. Substrate
for streaming server, OpenAI server, AND Dynamo backend.
- **`build_app`**: FastAPI app factory in
`fastvideo.entrypoints.streaming.server`. Currently exposes only
`/health` + `/v1/stream`. FE-required `/healthz`+`/readyz`+`/status`
migration is open follow-up #1.
- **`LLMProvider`**: protocol abstraction for prompt enhancer providers
(cerebras, cerebras_ifm, groq). Public schema currently restricts to
`Literal["cerebras", "groq"]`; `cerebras_ifm` is internal-only.
- **`compat.py`**: legacy kwargs translation layer (~370 lines). Scheduled
for death across PRs 14-17.
- **`prepare_for_compile`**: duck-type protocol method called via
`getattr(module, "prepare_for_compile", None)` before `torch.compile`.
Currently only Gemma3 implements it.
- **`SubprocessGpuPool`**: PR 7.6 public replacement for the internal
`realtime/local_runtime.GPUPool`. Per-GPU subprocess workers, typed
`GeneratorConfig` boundary.
- **PR 5.5**: streaming server subpackage skeleton — adds
`fastvideo/entrypoints/streaming/` parallel to `openai/`.
- **PR 7.10**: the unlock PR. Closes Q-5 (audio re-encode), Q-9 (Dynamo
progress), and PR 7.5's mid-segment cancellation TODO simultaneously.
## Live process map (as of 2026-05-03)
| Port | Service | Source |
|---|---|---|
| 8009 | `dreamverse-server` | running, `/readyz` 200, 1 warmed GPU worker |
| 5274 | `next-server` (dev) | running |
| 8000 | unknown FastAPI | not in handoff — verify before launching new BE |
## How this directory is maintained
- Source of truth for the integration story. Update when state changes.
- Each file has a "Last updated" header; bump when you edit.
- Cross-reference siblings via relative links; do NOT duplicate content.
- New entries: register in `../index.jsonl`.
- These files supersede the untracked source docs in the repo root and
`.agents/exploration/` — see [state.md](state.md) "Untracked but
present" section for disposition.
## Source documents (archived 2026-05-03)
The 7 source docs that this directory consolidates have been moved into
[`source-archive/`](source-archive/). They remain available for agents
who want the full unsynthesized rationale, but the synthesized memory
files in this dir are the canonical source of truth.
| Source doc | Lines | Synthesized into |
|---|---|---|
| [`source-archive/apirefactor.md`](source-archive/apirefactor.md) | 838 | [design.md](design.md) |
| [`source-archive/PR-plan.md`](source-archive/PR-plan.md) | 1145 | [pr-roadmap.md](pr-roadmap.md) |
| [`source-archive/dreamverse_review.md`](source-archive/dreamverse_review.md) | 390 | [state.md](state.md) + [decisions-log.md](decisions-log.md) |
| [`source-archive/handoff-nvfp4-launch-demo.md`](source-archive/handoff-nvfp4-launch-demo.md) | 518 | [state.md](state.md) + [quantization.md](quantization.md) + [open-threads.md](open-threads.md) |
| [`source-archive/streaming-server-upstream-plan.md`](source-archive/streaming-server-upstream-plan.md) | 539 | [streaming-server.md](streaming-server.md) + [decisions-log.md](decisions-log.md) |
| [`source-archive/dreamverse_integration.md`](source-archive/dreamverse_integration.md) | 285 | [cross-repo-surfaces.md](cross-repo-surfaces.md) |
| [`source-archive/video-generator-config-api-design.md`](source-archive/video-generator-config-api-design.md) | 93 | [design.md](design.md) (early-draft material) |
| `.agents/exploration/pr-link-review.md` | 29 | already promoted to `.agents/skills/review-pr-link/` (kept in exploration dir) |
See [`source-archive/README.md`](source-archive/README.md) for the
archive policy.
@@ -1,150 +0,0 @@
# Authors — Dreamverse Integration
**Status:** PERMANENT — keep around as the source of truth for who collaborated
on the dreamverse-integration work, even after every PR in the integration
scope has merged.
**Last updated:** 2026-05-05 (strategy reversal — single mega-PR #1288 on `will/ltx2_sr_port` replaces planned 6-PR split; #1287 closed; per [decisions-log.md D-17](decisions-log.md#d-17))
This file documents the human co-authors credited on every commit in the
dreamverse-integration scope (FastVideo public-API refactor, streaming server
upstream, GPU pool, prompt enhancer, NVFP4 wire-up, LTX-2 SR port). The
4 collaborators below worked on the FastVideo-internal precursor of this code
and are credited as co-authors on every public-side upstream commit via Git's
standard
[`Co-authored-by`](https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors)
trailer convention.
Scope-wise this is the dreamverse-integration-flavored mirror of the
top-level [`CO-AUTHORS.md`](../../../CO-AUTHORS.md), which is scoped to the
broader `will/ltx2_sr_port` 10-PR stack. The roster is identical; this file
exists so the dreamverse-integration memory dir is self-contained and
discoverable without traversing to the repo root.
## Co-author roster
| GitHub user | Real name | GitHub ID | Trailer email |
|---|---|---|---|
| [`@Davids048`](https://github.com/Davids048) | Junda (David) Su | 90978028 | `90978028+Davids048@users.noreply.github.com` |
| [`@RandNMR73`](https://github.com/RandNMR73) | Matthew Noto | 99706358 | `99706358+RandNMR73@users.noreply.github.com` |
| [`@XOR-op`](https://github.com/XOR-op) | (unset) | 17672363 | `17672363+XOR-op@users.noreply.github.com` |
| [`@jzhang38`](https://github.com/jzhang38) | Zhang Peiyuan | 42993249 | `42993249+jzhang38@users.noreply.github.com` |
## Verification — where these trailers appear
Verified via `gh pr view <PR> --json commits --jq '.commits[].messageBody'`
across every PR in the integration scope:
| PR | Branch | Status | Trailers present on every commit |
|---|---|---|---|
| #1257 | `will/api_7.6` (GPU pool upstream) | ✅ merged 2026-05-04 | yes (4/4) |
| #1258 | `will/api_7.7` (prompt enhancer + LLMProvider) | ✅ merged 2026-05-04 | yes (3/3) |
| #1284 | `will/api_7.8` (streaming auxiliaries) | ✅ merged 2026-05-04 | yes (2/2) |
| #1286 | `will/api_7.9` (streaming router) | ✅ merged 2026-05-05 at `2aaeee2a` (squash) | yes on commits 1-3; commit `a152cb77` (`[fix] streaming: router polish`) was missing trailers but got squashed into the merge commit, so the merge commit on main inherits the trailers from the other 3. The trailerless cherry-pick partner (`40e265b8` on `will/ltx2_sr_port`) was dropped by the post-#1286 rebase — gap permanently resolved. |
| #1287 | `will/api_7.10` (`generate_async` + `VideoEvent`) | ❌ CLOSED 2026-05-05 — superseded by #1288 per [D-17](decisions-log.md#d-17) | yes on all 3 commits (now part of #1288's chain) |
| **#1288** | **`will/ltx2_sr_port`** (mega-PR — full stack: SR runtime + NVFP4 + generate_async + Dynamo contract + agents memory + integration-review) | 🟢 OPEN, MERGEABLE at `b36bdbc9`, 36 commits / 70 files / ~+13.0k LOC (post STACK.md removal) | yes on all 36 commits |
Aggregate count across `will/ltx2_sr_port` (top of stack) at the time of
writing: 32-33 commits per co-author, matching the 32 commits in the stack
on top of base `cfccd292`. Numbers stay consistent because the rebase
command (see "How the trailers were applied" below) walks every commit.
## Trailer block (copy-paste ready)
The trailers added to every commit on `will/ltx2_sr_port` and every
dreamverse-integration PR:
```
Co-authored-by: Junda (David) Su <90978028+Davids048@users.noreply.github.com>
Co-authored-by: Matthew Noto <99706358+RandNMR73@users.noreply.github.com>
Co-authored-by: XOR-op <17672363+XOR-op@users.noreply.github.com>
Co-authored-by: Zhang Peiyuan <42993249+jzhang38@users.noreply.github.com>
```
For one-off `git commit -m` invocations, use `--trailer` flags:
```bash
git commit -m "..." \
--trailer "Co-authored-by: Junda (David) Su <90978028+Davids048@users.noreply.github.com>" \
--trailer "Co-authored-by: Matthew Noto <99706358+RandNMR73@users.noreply.github.com>" \
--trailer "Co-authored-by: XOR-op <17672363+XOR-op@users.noreply.github.com>" \
--trailer "Co-authored-by: Zhang Peiyuan <42993249+jzhang38@users.noreply.github.com>"
```
`--trailer` is idempotent (dedupes by full `key: value`) so re-running is safe.
## Why no-reply emails
GitHub's `<id>+<username>@users.noreply.github.com` form is the most reliable
way to link a `Co-authored-by` trailer to a GitHub account. It:
- Always works regardless of whether the user has a public verified email
- Survives the user changing their primary email
- Doesn't expose anyone's personal email to git history
- Is the format GitHub itself produces when you click "Add co-author" in the
web UI
(All 4 collaborators have this email already used in `FastVideo-internal`
git history, verified via `git log --all` on that repo.)
## How the trailers were applied (bulk rebase)
```bash
git rebase --exec '
git commit --amend --no-edit \
--trailer "Co-authored-by: Junda (David) Su <90978028+Davids048@users.noreply.github.com>" \
--trailer "Co-authored-by: Matthew Noto <99706358+RandNMR73@users.noreply.github.com>" \
--trailer "Co-authored-by: XOR-op <17672363+XOR-op@users.noreply.github.com>" \
--trailer "Co-authored-by: Zhang Peiyuan <42993249+jzhang38@users.noreply.github.com>"
' origin/main will/ltx2_sr_port
```
After running, re-slice all 10 split branches per [`STACK.md`](../../../STACK.md)
and force-push the published branches (`will/api_7.9`, `will/ltx2_sr_port`).
## How to add a new co-author later
1. Add the user to the roster table above (and the top-level
[`CO-AUTHORS.md`](../../../CO-AUTHORS.md) — keep them in sync).
2. Append their `Co-authored-by` line to the trailer block above.
3. Re-run the bulk rebase command on `will/ltx2_sr_port` — git's trailer
dedupe handles the existing 4; the new one gets appended.
4. Re-slice all split branches per [`STACK.md`](../../../STACK.md).
5. Force-push the published branches.
## What we do NOT add
Per the repo's top-level [`AGENTS.md`](../../../AGENTS.md):
> Never add any coding agent or models such as Claude (or Claude Code), GPT,
> Codex or others as a co-author in commits or PRs. Do not include
> `Co-Authored-By: Claude ...` trailers or "Generated with Claude Code" and
> other such lines.
So no `Co-authored-by: Claude <noreply@anthropic.com>`, no
`Generated with Claude Code` footer, no `Cursor <cursoragent@cursor.com>`
trailer (one such commit exists on `will/ltx2_sr_port` from a pre-policy
external contribution and stays grandfathered; new commits MUST NOT introduce
the pattern). Only human collaborators.
## Known gaps
**Resolved 2026-05-05 by the post-#1286 rebase.** The two trailerless
commits (`a152cb77` on `will/api_7.9` and `40e265b8` on
`will/ltx2_sr_port`) are no longer reachable from any active branch:
- `a152cb77` was absorbed into squash merge `2aaeee2a` on main, which
inherits the trailers from the other 3 commits in the squash.
- `40e265b8` was dropped by the post-#1286 rebase of
`will/ltx2_sr_port`.
Both still exist on the local backup `will/ltx2_sr_port-pre-1286-rebase`
for archeological reference. No further action needed.
## See also
- [`../../../CO-AUTHORS.md`](../../../CO-AUTHORS.md) — top-level stack-scoped
co-authors file (same roster, broader scope)
- [`../../../STACK.md`](../../../STACK.md) — 10-PR split layout for
`will/ltx2_sr_port` (re-slice commands live here)
- [`pr-roadmap.md`](pr-roadmap.md) — per-PR status within the
dreamverse-integration scope
@@ -1,277 +0,0 @@
# Cross-Repo Surfaces — Dreamverse + Dynamo
How Dreamverse consumes FastVideo today, what's already shared, what's
ad hoc, and what migrations land alongside each PR. Plus the Dynamo
backend contract.
For the streaming-server side see [streaming-server.md](streaming-server.md).
For the API design see [design.md](design.md). For PR sequence see
[pr-roadmap.md](pr-roadmap.md).
**Last updated:** 2026-05-03.
## The three surfaces
Dreamverse depends on FastVideo across three surfaces (in order of
stability):
1. **Pipeline construction** (stable)
2. **Realtime runtime** (in flight: PRs 7.5/7.6)
3. **Continuation state** (PR 7 typed; PR 7.6 wires server-held)
## Surface 1: Pipeline construction (stable)
`Dreamverse/server/video_generation.py:VideoGenerationWorker` calls
`VideoGenerator.from_pretrained(...)`.
After PR 6 the typed `GeneratorConfig` path exists; **as of `d80c2a8`
(May 2)** Dreamverse migrated to the typed path:
| Dreamverse usage | FastVideo public surface (post-PR 6) |
|---|---|
| `VideoGenerator.from_pretrained(model_path, ltx2_refine_enabled=…, …)` | `VideoGenerator.from_pretrained(config=GeneratorConfig(...))` |
| Flat `torch_compile_kwargs={…}` dict | `engine.compile.{backend,fullgraph,mode,dynamic,extras}` |
| `ltx2_vae_tiling=True` | `pipeline.vae_tiling=True` |
| `ltx2_refine_*` family | `pipeline.preset_overrides.refine.*` + `pipeline.components.upsampler_weights` |
| `enable_torch_compile_text_encoder` | `engine.compile.text_encoder_enabled` |
Refine knobs moved from `ltx2_refine_*` flat kwargs into
`preset_overrides["refine"]`. **The in-memory `pipeline_config` pin**
(`dit_config.quant_config = NVFP4Config()`) keeps using the legacy
`experimental["pipeline_config"]` carrier because typed
`transformer_quant: "NVFP4"` doesn't yet support setting
`layer_profile` (see [open-threads.md](open-threads.md) follow-up #4 +
[quantization.md](quantization.md)).
Legacy flat-kwarg path stays supported via `compat.py`; migration is
opt-in. PR 13's deprecation warnings are the eventual nudge.
## Surface 2: Realtime runtime (in flight: PRs 7.5–7.6)
`Dreamverse/server/runtime/factory.py` selects a runtime backend at
process start:
```python
def create_runtime_pool() -> RuntimePool:
if os.getenv("FASTVIDEO_REALTIME_BASE_URL"):
return FastVideoRealtimePool(base_url=..., ws_url=..., default_model_id=...)
return GPUPool(get_available_gpus()) # in-process, wraps
# fastvideo.entrypoints.realtime.local_runtime
```
Both backends speak the same `RuntimePool` / `RuntimeSlot` Protocol
(`server/runtime/interfaces.py`):
- `acquire(client_id, websocket=None) -> (gpu_id, RuntimeSlot)`
- `release(client_id)`
- `RuntimeSlot.{join_user, user_step, leave_user, register_stream_queue, ...}`
Today both impls reach into FastVideo-internal's
`fastvideo.entrypoints.realtime.local_runtime` (which exposes
`RealtimeRuntimeConfig`, `GPUPool`, `GPUSlot`). The remote backend talks
HTTP+WS to a separately-deployed runtime of the same shape.
**Contract that PR 7.5/7.6 must preserve:**
- `RealtimeRuntimeConfig` accepts `model_registry`, `default_model_id`,
`default_height/width/num_frames/fps/num_inference_steps/guidance_scale/seed/negative_prompt`,
`default_ltx2_image_crf`, `startup_warmup_{enabled,prompt,timeout_seconds}`.
- `GPUPool(gpu_ids: list[int], config: RealtimeRuntimeConfig)` constructor.
- `pool.initialize() / shutdown() / acquire() / release() / get_status()`.
- HTTP endpoints on the remote variant: `GET /healthz`, `GET /readyz`,
`GET /status`, `WS /ws`. (Already match what
`Dreamverse/server/routes/health.py` consumes.)
**These three health routes still need to migrate into FastVideo's
`build_app` to make `BE_FLAVOR=fastvideo` FE-compatible** — see
[streaming-server.md](streaming-server.md) "build_app route contract" +
[open-threads.md](open-threads.md) follow-up #1.
When PR 7.6 lands the upstream of `fastvideo/entrypoints/realtime/`,
Dreamverse should not need any code change unless the import path
renames. Decided: keep `streaming/` (post-PR-5.5 public name); ship
`realtime/__init__.py` as a re-export with `DeprecationWarning` for one
release cycle.
### Note on `default_ltx2_image_crf`
Dreamverse's `RealtimeRuntimeConfig` includes `default_ltx2_image_crf`.
The April 26 Dreamverse review (D-8) showed this getting passed to
`SamplingParam(...)` and **silently dropped** by the public schema. Post
`d80c2a8` (May 2 typed-config refactor), the migration target is
`request.stage_overrides.refine.image_crf` (per
[design.md](design.md) compatibility mapping table).
**Whether `d80c2a8` actually wired this through, or it's still latent,
is unverified.** See [open-threads.md](open-threads.md) item D-8.
## Surface 3: Continuation state (PR 7)
`Dreamverse/server/video_generation.py:89 ContinuationState` is
Dreamverse's hand-rolled per-session state holder. PR 7 introduced the
typed equivalent at
[`fastvideo/pipelines/basic/ltx2/continuation.py`](file:///home/william5lin/FastVideo/fastvideo/pipelines/basic/ltx2/continuation.py).
### Field mapping
| Dreamverse | PR 7 `LTX2ContinuationState` | Notes |
|---|---|---|
| `video_images: list[PIL.Image]` | `video_frames: list[np.ndarray]` (uint8 H×W×3) | numpy is leaner; Dreamverse already round-trips PIL→numpy→PIL just to add noise |
| `audio_latents: torch.Tensor` `[B, C, T, mel]` | `audio_latents: torch.Tensor` (safetensors-serialized; bf16-safe) | unchanged shape; safetensors preserves bf16 |
| `LTX2_VIDEO_CONDITIONING_FRAME_IDX` (env) | `video_conditioning_frame_idx: int` | env constant → per-state field |
| `LTX2_VIDEO_CONDITIONING_STRENGTH` (env) | `video_conditioning_strength: float` | env constant → per-state field |
| `AUDIO_CONDITIONING_NUM_FRAMES` (env) | `audio_conditioning_num_frames: int` | env constant → per-state field |
| `AUDIO_CONDITIONING_STRENGTH` (env) | `audio_conditioning_strength: float` | env constant → per-state field |
| `audio_lps` (passed into `apply_audio`) | `audio_sample_rate: int \| None` | analogous; rename worth confirming with audio team |
| Computed `prefix_sec` per segment | `video_position_offset_sec: float` | **see open question below** |
| `segment_idx` (param to `apply_*`) | `segment_index: int` | per-state field |
| `VIDEO_CONTEXT_NOISE`, `AUDIO_CONTEXT_NOISE`, `ENABLE_AUDIO_COND` | not on state | runtime policy / regularization knobs, not portable session data |
| `apply_video / apply_audio / save_video / save_audio_latents / clear` | not on PR-7 state class | state is a pure data carrier; runtime owns lifecycle policy |
PR 7 is a strict superset of Dreamverse's data model **plus** lifts
several env globals into per-session typed fields.
### Lifecycle mapping
| Dreamverse pattern | `SessionStore` API |
|---|---|
| `self.continuation = ContinuationState()` per session | `state = session_store.snapshot(sid) or LTX2ContinuationState()` |
| `apply_video(req_kwargs, segment_idx)` + `apply_audio(req_kwargs, segment_idx, audio_lps)` | `state = session_store.snapshot(sid)`; runtime builds request from `state.video_frames` / `state.audio_latents` |
| `save_video(frames)` + `save_audio_latents(latents)` | runtime constructs new `LTX2ContinuationState`, `session_store.store(sid, ...)` |
| `clear()` at end of session | `session_store.drop(sid)` |
`SessionStore` and `BlobStore` ABCs ship with thread-safe in-memory
defaults (`InMemorySessionStore`, `InMemoryBlobStore`). Dreamverse can
adopt them as-is for the local runtime; remote runtimes can plug in
redis-backed implementations later.
### Wire format (HTTP/WS round-trip)
Dreamverse's `FastVideoRealtimePool` already speaks the realtime
runtime's HTTP+WS protocol. When PR 7.5/7.6 land state emission on the
server side, the on-the-wire payload is the public envelope:
```json
{
"kind": "ltx2.v1",
"payload": {
"schema_version": 1,
"segment_index": 3,
"video_conditioning_frame_idx": 9,
"video_conditioning_strength": 0.75,
"audio_sample_rate": 24000,
"audio_conditioning_num_frames": 5,
"audio_conditioning_strength": 0.5,
"video_position_offset_sec": 0.2,
"video": {"frames_b64": ["..."]},
"audio": {"safetensors_b64": "..."},
"metadata": {}
}
}
```
JSON-serializable end-to-end; safetensors blob preserves audio dtype
(incl. bf16). For payloads above the inline threshold a `BlobStore`
indirection replaces the b64-encoded body with `{"blob_id": "..."}`;
the blob itself stays inside the runtime that produced it.
## Migration plan per PR
| PR | Dreamverse action |
|---|---|
| PR 6 (landed) | Typed `GeneratorConfig` available; flat-kwarg path still works via compat. Optional migration. |
| PR 7 (landed) | Typed `LTX2ContinuationState` available. ~50-line Dreamverse PR: replace `server/video_generation.py:89` import; move `apply_*`/`save_*`/`clear` off the state class onto `VideoGenerationWorker`; read knobs from typed state instead of env globals; swap `list[PIL.Image]` → `list[np.ndarray]`. |
| PR 7.5 (open) | Streaming server skeleton — Dreamverse's `runtime/factory.py` either keeps building `GPUPool` from `RealtimeRuntimeConfig` (current path), or migrates to `ServeConfig.streaming` shape and invokes `fastvideo serve --config realtime.yaml`. Dreamverse's `RuntimePool`/`RuntimeSlot` Protocol can stay in place. |
| PR 7.6 (branch ready) | GPU pool upstream — `local_runtime.py` import becomes a public import with same symbols (`RealtimeRuntimeConfig`, `GPUPool`, `get_available_gpus`). Per-GPU continuation state inside the worker becomes a `SessionStore` reference (Dreamverse doesn't see this). `request.state` / `result.state` round-trip starts working end-to-end on the local runtime. |
| PR 7.10 (planned) | `generate_async` is canonical. Dreamverse's per-segment `user_step` flow can migrate from sync `generate_video(..., **kwargs)` to consuming the typed event stream. Optional; sync wrapper stays. |
## Dynamo backend contract
**FastVideo does not host any Dynamo code.** The backend package
(`args.py`, `main.py`, `backend.py`, `register.py`, `health_check.py`,
adapter, Dockerfile) lives entirely in the Dynamo repo at
`components/src/dynamo/fastvideo/`, modeled on
`components/src/dynamo/sglang/`.
FastVideo's only obligation is to expose a stable, typed Python API
that Dynamo's backend package imports.
### Contract surface
| Surface | Exposed as |
|---|---|
| Construction | `VideoGenerator.from_pretrained(model_path, **typed_kwargs)` (typed_kwargs = a stable subset from `GeneratorConfig`; no flat LTX2 legacy) |
| Sync execution | `generator.generate_video(request: GenerationRequest) -> VideoResult` |
| Async execution | `generator.generate_async(request: GenerationRequest) -> AsyncGenerator[VideoEvent, None]` (PR 7.10) |
| Typed request | `fastvideo.api.GenerationRequest`, `SamplingConfig`, `InputConfig` |
| Typed result | `VideoResult` with `video_bytes` or tensor frames + optional `ContinuationState` |
| Continuation | `ContinuationState(kind, payload)` — schema-versioned payloads |
| Health-check input | `VideoGenerator.default_health_check_request() -> GenerationRequest` (256x256 / 8 frames / 1 step) |
| Config dump | `GeneratorConfig.to_dict()` / `ServeConfig.to_dict()` |
### Request/response mapping (Dynamo ↔ FastVideo)
```
NvCreateVideoRequest -> fastvideo.api.GenerationRequest
prompt -> sampling.prompt
size="WxH" -> sampling.width, sampling.height
seconds -> (seconds * nvext.fps) -> sampling.num_frames
input_reference -> input.image_path / input.video_path
nvext.fps -> sampling.fps
nvext.num_frames -> sampling.num_frames (overrides seconds*fps)
nvext.num_inference_steps -> sampling.num_inference_steps
nvext.guidance_scale -> sampling.guidance_scale
nvext.seed -> sampling.seed
nvext.negative_prompt -> sampling.negative_prompt
response_format -> (handled by adapter at output)
VideoFinalEvent -> NvVideosResponse
video_bytes -> data[0].b64_json (if response_format=b64_json)
video_url (after upload) -> data[0].url (if response_format=url)
metadata.inference_time_s -> inference_time_s
```
All fields exist on FastVideo's typed schema after PR 6 expansion (typed
LTX2 kwargs) + PR 7.10 (`generate_async` + health check).
### Reference: PR ai-dynamo/dynamo#7544
Closed draft establishing the Dynamo backend shape. Two frictions
identified:
1. Flat legacy LTX2 kwargs — solved by PR 6.
2. Sync-only generation — solved by PR 7.10's `generate_async`.
Next iteration of this PR (or its successor) will reopen against PR 8's
docs reference and land cleanly.
## Open questions across surfaces
| # | Question | Source | Status |
|---|---|---|---|
| Q-1 | Multi-model GPU pool | dreamverse_review D-1 | Deferred (production single-model) |
| Q-2 | LTX-2 prompt orchestration promotion to public | dreamverse_review D-2 | Open; consumer-side until 2nd consumer |
| Q-3 | Race-based provider fallback | dreamverse_review D-3 | Open; sequential is current public |
| Q-4 | Router upstream skip on Dreamverse | dreamverse_review D-4 | Resolved (PR 7.9 lands publicly, Dreamverse doesn't consume) |
| Q-5 / D-5 | `generate_async` cutover (audio re-encode) | dreamverse_review | **Blocked on PR 7.10** |
| D-6 | Don't upstream `realtime/local_runtime.py` | dreamverse_review | Resolved (Dreamverse switches to `streaming.gpu_pool.SubprocessGpuPool`) |
| D-7 / Q-6 | FP4Config public colocation | dreamverse_review | **Resolved May 2** — public NVFP4 landed with lazy flashinfer |
| D-8 | `ltx2_image_crf` silently dropped | dreamverse_review | **Unverified post-`d80c2a8`** — see [open-threads.md](open-threads.md) |
| D-9 | `aarch64-conda-linux-gnu-cc` triton compile failure | dreamverse_review | Operational; `ENABLE_TORCH_COMPILE=0` workaround |
| D-10 | Warmup OOM on shared GPU | dreamverse_review | Operational; idle-GPU pre-warm probe |
| D-11 | ffmpeg `Broken pipe` on disconnect | dreamverse_review | Cosmetic logging cleanup |
| — | `video_position_offset_sec` semantics (persistent vs per-segment) | dreamverse_integration | **Open — needs decision before PR 7.6 emits state** |
| — | `SessionStore` / `BlobStore` lifecycle (TTL/eviction/blob-drop) | dreamverse_integration | Open — defer to PR 7.5 design pass |
See [decisions-log.md](decisions-log.md) for full rationale per
decision.
## Don't / Cautions
- **Don't pop the Dreamverse stash on this branch.** It's 3867 lines of
orphan modular refactor with broken absolute imports.
- **Don't change `RealtimeRuntimeConfig` shape without coordinating
with Dreamverse `runtime/factory.py`.**
- **Don't promise public compatibility for private Dreamverse-only
field aliases.** Those belong in the private adapter layer per design
spec.
@@ -1,710 +0,0 @@
# Decisions Log — D + Q Resolutions
Cross-doc consolidated decision log. Each entry: ID, source doc,
question/decision, rationale, current status.
For implementation status see [pr-roadmap.md](pr-roadmap.md). For
follow-up actions see [open-threads.md](open-threads.md).
**Last updated:** 2026-05-05 (added D-12 — GpuPool layer separation, Oracle review post-#1257-merge; added D-13 — prompt enhancer / LLMProvider abstraction shape, Oracle review pre-#1258-merge; added D-14 — streaming auxiliaries cohesion, Oracle review during #1284 review cycle; added D-15 — streaming router placement + sticky/active-active deferral, Oracle review during #1286 review cycle; added D-16 — streaming router polish round 2, second-pass review on top of D-15 covering bridge cancellation hygiene, registry state machine, httpx hard-fail, replica YAML parsing, and `websockets` dep; added D-17 — strategy reversal: abandon 6-PR split in favor of single mega-PR #1288 on `will/ltx2_sr_port`; added D-18 — Option B+ chosen: Dreamverse FE+product-server move into FastVideo as `apps/dreamverse/` subfolder while generic backend stays at `fastvideo.entrypoints.streaming.*`; integration-review.md deprecated, integration-plan.md is the executable migration plan).
## Status legend
- ✅ **Resolved** — decision made and implementation complete (or no implementation needed)
- 🟡 **Deferred** — decision made, implementation deferred to a known PR
- 🔴 **Open** — needs decision
## Post-merge architecture decisions
### D-18: Option B+ — Dreamverse becomes `apps/dreamverse/` subfolder under FastVideo
**Status:** ✅ Resolved 2026-05-05. [integration-plan.md](integration-plan.md) is the executable migration plan; [integration-review.md](integration-review.md) is deprecated but kept for drift audit + OSS precedents.
**Source:** User decision after reviewing [integration-review.md](integration-review.md)'s Option D recommendation.
**Question:** [integration-review.md](integration-review.md) recommended **Option D** — Dreamverse stays a separate repo, generic backend (streaming runtime, GPU pool, prompt enhancer, router) merges into `fastvideo.entrypoints.streaming.*`. The user reviewed this and chose a different shape: keep the generic-backend principle from Option D but ALSO move the Dreamverse FE + product server into FastVideo as a subfolder (`apps/dreamverse/`). Combination is "Option B+" (Option B layout with Option D's backend principle).
**Decision:** Option B+. Concrete shape:
- **One repo**: `hao-ai-lab/FastVideo`. Dreamverse repo gets archived after migration completes.
- **Python ML library** stays at root: `fastvideo/`, `fastvideo-kernel/`.
- **Generic backend** stays at `fastvideo.entrypoints.streaming.*` (already there per #1257/#1258/#1284/#1286/#1288).
- **Dreamverse product** moves into `apps/dreamverse/{server,web,prompts,serve_configs,scripts}/`.
- **Tooling**: uv workspace for Python (`[tool.uv.workspace] members = ["apps/dreamverse/server"]`), standalone pnpm for the FE (no root `package.json`), split CI workflows with path-filter triggers.
**Rationale:**
- Drops the cross-repo coordination overhead identified in the post-#1286 rebase cycle (D-17 handled by consolidating into mega-PR; D-18 prevents the next round of cross-repo coordination from happening).
- Keeps the architectural separation Option D recommended (FastVideo owns reusable runtime; product owns product). The boundary is now `apps/dreamverse/` directory rather than two repos.
- Single repo means atomic cross-cutting refactors (e.g. GpuPool API change + Dreamverse adoption) ship as one PR.
- OSS precedents support the shape (chainlit uv-workspace + pnpm; open-webui Python + Svelte with paths-ignore CI). The librarian explicitly noted no precedent for "Python ML library + Next.js product merged into library namespace" — but this isn't that pattern. Dreamverse goes into a sibling directory, NOT into `fastvideo.entrypoints.dreamverse.*`. Library namespace stays clean.
**Why not Option D (separate repos):**
- Each upstream merge into FastVideo invalidates Dreamverse's lockfile/imports; the post-#1286 rebase showed this requires coordination overhead that scales with feature velocity.
- Cross-repo contract tests catch shape drift but not behavior drift.
- Two repos means two `AGENTS.md`, two CI configs, two release stories, two Dependabot dashboards.
**Why not Option C (full merge into `fastvideo.entrypoints.dreamverse.*`):**
- Forces FastVideo to ship Tailwind config + curated preset JSON + Next.js build artifacts.
- Locks Dreamverse product cadence to FastVideo PyPI releases.
- Librarian: "no 1:1 precedent for Python ML library + Next.js product merged into library namespace" — argues against this.
**Why not Option B (subfolder, but generic backend folded into `apps/dreamverse/server/`):**
- Other consumers (Dynamo, future streaming clients) need the backend without the Dreamverse product. Folding the backend under `apps/dreamverse/server/` would force Dynamo to either depend on `apps/` paths (ugly) or carry a fork.
**Implications:**
- [integration-review.md](integration-review.md) is **deprecated** (banner header + reading-guide demotion). Kept in tree for drift audit + OSS precedent reference.
- [integration-plan.md](integration-plan.md) is the **canonical executable plan** with 7 phases (Phase 0: land #1288; Phase 1: skeleton + tooling; Phase 2: backend move; Phase 3: FE move; Phase 4: promote generic-pending; Phase 5: prompt enhancer fork retirement; Phase 6: CI/release cutover; Phase 7: archive Dreamverse repo).
- Dreamverse repo will be **archived** at end of Phase 7 — not before.
- Dreamverse history does NOT migrate cross-repo via `git mv` (technical limitation); original history stays in archived Dreamverse repo, and Phase 2 PR body records the source SHA(s).
- New top-level `apps/` directory created — must be excluded from FastVideo PyPI wheel via `[tool.setuptools.packages.find] exclude = ["apps*", ...]`.
- Drift items from [integration-review.md](integration-review.md) get folded into specific phases of [integration-plan.md](integration-plan.md) (e.g. health routes → Phase 4, DR-1 → Phase 5).
**Open questions deferred to phase planning:**
- DR-2 (`cerebras_ifm`): public Literal vs Dreamverse-side custom provider — decide before Phase 5.
- VPO (`video_position_offset_sec` semantics): persistent vs per-segment — decide in Phase 4.
- Cross-repo history: fresh import vs `git subtree` import — decide before Phase 2.
- CORS / write-endpoint security policy: dev-only vs auth vs firewall — decide before Phase 6.
### D-17: Abandon 6-PR split — land everything as single mega-PR #1288
**Status:** ✅ Resolved 2026-05-05. PR #1287 closed; PR #1288 opened on `will/ltx2_sr_port` covering the full chain.
**Source:** User decision after observing the post-#1286 rebase + re-slice cycle.
**Question:** The original plan ([STACK.md](../../../STACK.md), [pr-roadmap.md](pr-roadmap.md)) called for the remaining `will/ltx2_sr_port` content (after PRs 7.5/7.6/7.7/7.8/7.9 landed) to ship as 6 stacked PRs: 7.10 (#1287, generate_async), 8 (server contract docs), LTX-2 SR runtime, NVFP4, post-fixes, agents-cleanup. PR #1287 was opened on 2026-05-05 as the first slice. Should the remaining 5 slices be opened sequentially as planned, or should everything be consolidated into one PR?
**Decision:** Consolidate. Close #1287; open one mega-PR (#1288) on `will/ltx2_sr_port` covering all 34 commits / 71 files / +13,074 LOC at once.
**Rationale:**
- The post-#1286 rebase + re-slice cycle exposed real overhead: backup branch, interactive rebase with manual `drop` directives, force-push, re-slice 6 bookmarks, push next slice as new remote, open new PR, update memory dir. Repeating that 6 more times for the remaining slices accumulates substantial review-coordination overhead with diminishing structural benefit.
- The 6 layers are not independent in the way that landed PRs 7.5-7.9 were. PR 7.10 (`generate_async`) is the only API-shape change; PR 8 is docs+tests on top; LTX-2 SR / NVFP4 / post-fixes / agents-cleanup are feature/fix/docs work that doesn't shape the public API. Reviewing them as one ordered diff is at least as easy as reviewing 6 stacked PRs whose dependencies must be tracked manually.
- Single PR keeps CI / merge queue simpler and avoids the 6-PR cascade where every upstream merge invalidates the chain below it.
**Implications:**
- [STACK.md](../../../STACK.md) (top-level, 10-PR split tracker) is **deprecated**. Kept in tree as a historical artifact with the merged half (PRs 1-4 of the 10) accurate. Safe to delete in a follow-up.
- [authors.md](authors.md), [`CO-AUTHORS.md`](../../../CO-AUTHORS.md) — co-author roster is unchanged; trailers still apply per-commit on every commit in the consolidated PR.
- [runbook.md](runbook.md) — "After a PR merges (re-slice protocol)" section replaced by a simpler "After PR #1288 merges" section.
- Local split bookmarks (`will/api_7.10`, `will/api_8`, `will/ltx2_sr_runtime`, `will/ltx2_nvfp4`, `will/ltx2_post_fixes`, `will/agents_cleanup`) are no longer maintained; safe to delete locally.
- `origin/will/api_7.10` — pushed during the #1287 cycle; can be deleted on origin once #1287 close-cleanup completes.
**Watch outs:**
- The PR is large (71 files, +13,074 LOC). Reviewers will need commit-by-commit review; the PR body structures the layers in commit order to make this tractable.
- If #1288 becomes too large to merge cleanly later (e.g. main moves significantly underneath it), the fallback is to re-split — but the current expectation is to land it as-is.
### D-12: `GpuPool` layer separation — keep distinct from `VideoGenerator`
**Status:** ✅ Resolved (interim) + 🟡 Deferred long-term shape to PR 7.10.
**Source:** Oracle review on 2026-05-04, post-PR-#1257 merge.
**Question:** Should `fastvideo.entrypoints.streaming.GpuPool` (PR #1257) be
folded into `fastvideo.entrypoints.video_generator.VideoGenerator`, or kept
separate? Three alternatives were evaluated:
| Alt | Approach | Verdict |
|---|---|---|
| A | Status quo — `VideoGenerator` (single inference call) and `GpuPool` (multi-session orchestration) stay separate | ✅ Correct as **interim** |
| B | `VideoGenerator` absorbs the pool's role (`from_pretrained_pool`, `acquire/release/run`) | ❌ **Wrong layer.** Conflates execution with serving scheduler. |
| C | `GpuPool` becomes a thin **session-aware async executor** over PR 7.10's `generate_async` | ✅ Correct **long-term destination** |
**Decision:** Alt A as interim; evolve toward Alt C once PR 7.10 lands
`generate_async`. Do NOT pursue Alt B.
**Rationale:**
- `VideoGenerator` is a library handle — "execute one request, possibly
across ranks via `MultiprocExecutor`/`RayDistributedExecutor`."
- `GpuPool` is serving infrastructure — "schedule N concurrent sessions
across N independent replicas, with sticky session-to-GPU affinity for
cache locality."
- These are different layers driven by different consumers (a Python
script doing `gen.generate(req)` vs. a WebSocket server with sticky
sessions). Folding them muddies both surfaces.
**Key finding — `MultiprocExecutor` and `SubprocessGpuPool` are orthogonal,
not redundant:**
| Layer | Job | Granularity |
|---|---|---|
| `MultiprocExecutor` (`fastvideo/worker/`) | TP/SP shard ONE inference call across N GPU ranks | per-call |
| `streaming_generator.py` (existing real-time path) | Per-frame streaming via `MultiprocExecutor.submit_step`/`get_result` | per-step within one generator |
| `SubprocessGpuPool` (`entrypoints/streaming/`, PR #1257) | Serve N concurrent sessions on N replicas, sticky-bound | per-session |
Both spawn subprocesses because **CUDA contexts demand process boundaries**,
not because they solve the same problem. Sharing low-level lifecycle
utilities (process spawn, queue plumbing, shutdown) is a future refactor;
unifying the abstractions is wrong.
**Sticky binding stays in the pool, NOT in `VideoGenerator`:** sticky
session-to-GPU affinity is a serving policy driven by LTX-2's per-GPU
continuation cache (last-9-decoded-frames + audio-latents). Different
consumers want different policies — stateless OpenAI HTTP wants
per-request leasing; LTX-2 streaming wants sticky affinity; per-frame
real-time streaming wants a continuous queue. Keeping policy in the pool
keeps `VideoGenerator` policy-free.
**Specific risks flagged in PR #1257 (already merged):**
| Risk | Mitigation (when relevant) |
|---|---|
| `GpuPool.run() -> Any` is sync — fine for whole-segment dispatch, blocks on cancellation | Replace with `run_async() -> AsyncIterator[VideoEvent]` in PR 7.10 cycle (`generate_async` makes this trivial) |
| `PoolAssignment.gpu_id: int` assumes one-GPU-per-worker | Don't lock as public API. Future may need `device_ids: list[int]` for topology-aware pooling (one worker = group of GPUs running internal `MultiprocExecutor`) |
| `GpuPool` could be documented as the canonical FastVideo serving API | Mark as **experimental / server-internal** in docstring until PR 7.10 lands. Don't include in user-facing API docs yet |
| Memory: N processes = N model replicas (~10-50 GB each) | Expected for concurrent serving with crash isolation. CUDA IPC weight sharing loses isolation; CPU-shared-memory loading helps host RAM not device. Real scalable path is topology-aware pooling later. |
**Action items (carried into post-7.10 cycle):**
- [ ] Update `GpuPool` ABC docstring to note "API may change post-PR-7.10"
- [ ] Plan to replace `run()` with `run_async() -> AsyncIterator[VideoEvent]` in PR 7.10 cycle
- [ ] Don't promote `gpu_id: int` to public API; revisit shape post-7.10
- [ ] Consider clarifying field naming (e.g. `worker_id` is the stable identifier; `gpu_id` is current-impl detail)
- [ ] When opening 7.10's PR, have it consume `generate_async` from `GpuPool.run_async` end-to-end
**Open thread it touches:** PR 7.10 (`open-threads.md` item D — generate_async)
unblocks Alt C and is the natural place to land the API shape change.
### D-15: Streaming router (PR #1286) — keep in-repo, defer sticky / active-active
**Status:** ✅ Resolved (interim). Pre-merge polishes applied. Three follow-up
items tracked.
**Source:** Oracle review on 2026-05-05, during PR #1286 review cycle.
**Question:** Where should the multi-replica WebSocket router live? Should it
ship at all (vs. delegating to nginx/envoy)? Should sticky session routing
or weighted/round-robin balancing be in the initial PR?
| Alt | Approach | Verdict |
|---|---|---|
| A | Status quo — `fastvideo/entrypoints/streaming/router/`, FastAPI-based, single-primary failover, lazy `httpx`/`websockets` imports | ✅ **Keep** |
| B | Move to separate package `fastvideo-router/` | ❌ **Premature** — adds packaging/release/compat overhead before evidence of independent adoption |
| C | Fold router into the streaming server itself (one app, mode flag) | ❌ Conflates router/generator lifecycles, mode-dependent config, drags inference deps into routing deployments |
| D | Replace with reverse proxy (nginx/envoy/HAProxy) recipes | ❌ Not as the SOLE answer — mature proxies don't naturally emit FastVideo typed `gpu_unavailable` frames or evolve with FastVideo session semantics. Recommend external proxies as a complement at high scale. |
| E | Add sticky session routing now | ❌ **Defer** — implementing correctly depends on where `session_id` is available (URL/header is easy, first JSON frame is invasive). Reconnects are rare today. |
| F | Add weighted / round-robin now | ❌ **Defer** — active-active without sticky routing is worse for LTX-2 continuation locality than active-passive failover |
**Decision:** Alt A — keep current shape. Apply pre-merge polishes; preserve
forward-compat for sticky routing.
**Rationale:**
- Python router is justified as a FastVideo-aware control-plane component,
not a replacement for Envoy/HAProxy. It can emit typed
`gpu_unavailable` frames, evolve with FastVideo session semantics,
and ship local/dev deployment without ceremony.
- The current abstraction is small + testable: `RouterConfig`,
`ReplicaRegistry`, `ReplicaStatus`, `HttpProbe` (Protocol/structural alias).
Adding strategy registries / telemetry interfaces / active-active policies
now would be over-engineering.
- Active-passive (single primary) is the right MVP for LTX-2 streaming —
preserves continuation cache locality (D-12 sticky binding rationale)
better than naive active-active.
- The biggest architectural risk isn't placement; it's accidentally baking
in unstated semantics. Define single-primary behavior + config validation
now so future active-active or sticky routing becomes additive.
**Pre-merge polishes applied (per gemini + Oracle review):**
| # | What | Why |
|---|---|---|
| 1 | `ReplicaRegistry.select()` docstring rewrite | gemini flagged "round-robin via insertion order" claim was misleading — implementation always returns `[0]`. Replaced with explicit "first healthy primary, else first healthy non-primary; this MVP picks first match within tier; round-robin/weighted deferred". |
| 2 | Refactored `run_health_check_loop` to share single `httpx.AsyncClient` across the loop's lifetime via `_build_default_probe()` async context manager | gemini flagged per-probe client instantiation as inefficient. With ~1 probe/second default polling, TCP/TLS handshake overhead is non-trivial; now reuses connection. Tests inject probes directly so the path stays bypassable. |
| 3 | Probe all replicas concurrently per cycle via `asyncio.gather(..., return_exceptions=True)` | gemini flagged sequential probes risk falling behind `health_check_interval_seconds` if replicas time out. Now per-cycle wall time = max(probe latencies), not sum. |
| 4 | `RouterConfig.__post_init__` validation | Oracle recommended: empty replicas, non-positive intervals/timeouts, thresholds < 1, non-`http(s)://` URLs, and >1 primary all `raise ValueError`. Surfaces misconfiguration at config-load instead of confusing runtime failures. |
| 5 | Migrated `@app.on_event("startup"/"shutdown")` to `@contextlib.asynccontextmanager`-based `_lifespan()` | Pre-merge — FastAPI deprecated the old API. Was tracked as the 7.9 caveat in pr-roadmap.md. |
**One review comment intentionally not implemented:**
| Comment | Decision |
|---|---|
| gemini medium: `_load_router_config` duplicates `fastvideo.api.parser.parse_config` logic | Kept manual flat-from-nested mapping. The YAML schema has nested `health_check:` block but `RouterConfig` is flat; using `parse_config` directly would require either restructuring `RouterConfig` to have a nested `HealthCheckConfig` (schema change beyond this PR's scope) or accepting incomplete parsing. Manual mapping is intentional and well-typed. |
All 4 review threads marked resolved on the GitHub PR.
**Action items (deferred):**
- [ ] Track sticky session routing extensibility — when needed, add
`ReplicaRegistry.select(routing_key: str | None = None)` so registry
evolution is additive; document upfront where `session_id` should
appear (URL/header preferred over first JSON frame to avoid
buffering/peeking)
- [ ] Track `_bridge_session()` backpressure note — fine for MVP because
`websockets` library provides basic transport backpressure, but at
high scale add max_size/timeouts or recommend Envoy/HAProxy in front
- [ ] If active-active multi-primary becomes a requirement, define
behavior (round-robin within healthy primaries, weighted, sticky-by-key)
rather than letting `select()` silently pick `[0]`
**Watch outs:**
- `session_id` in WebSocket URL/headers is the cleanest sticky-routing
hook. If it ends up only in the first JSON message, sticky routing
later will require buffering/peeking before backend selection.
- Multi-primary configs are now explicitly rejected by validation;
documented + enforced.
- `_bridge_session()` is fine for MVP (the libraries provide basic
backpressure), but not production-grade for edge load. Document the
limit.
**Open thread it touches:** open-threads.md items #13 (sticky routing),
#14 (bridge backpressure), #15 (multi-primary semantics).
### D-16: Streaming router polish round 2 — second-pass fixes on top of D-15
**Status:** ✅ Resolved. Applied as `[fix] streaming: router polish — bridge
cancel + state machine + deps` (`a152cb77` on `will/api_7.9`, `40e265b8` on
`will/ltx2_sr_port`).
**Source:** Second-pass review on PR #1286, 2026-05-05, after D-15's pre-merge
polishes landed.
**Question:** D-15 closed the structural review (placement, sticky/active-active
deferral, basic `__post_init__` validation). On a second pass through the same
files, five latent issues surfaced that weren't covered by gemini's first pass
or Oracle's structural review. Apply them on top of the merged D-15 polishes,
or queue for a follow-up PR?
**Decision:** Apply on top of `will/api_7.9` directly. All five are bug-class
or DX-class — none are scope-expanding architecture changes — so folding them
into PR #1286 keeps the router landing in one reviewable unit instead of
shipping a router PR plus an immediate follow-up fix PR.
**Fixes applied:**
| # | File | What | Why |
|---|---|---|---|
| 1 | `router/main.py::_bridge_session` | Replaced `asyncio.gather()` with `wait(FIRST_COMPLETED)` + explicit `cancel()`/drain + `_is_normal_disconnect()` classifier | `gather` waited for both directions; on client disconnect, the backend-reader task leaked and stayed pending. Backend `ConnectionClosed` also surfaced as an unhandled exception in server logs. New shape: first task to finish triggers explicit cancel of the other, both are drained, and only non-routine exceptions re-raise. |
| 2 | `router/registry.py::record_success` | Split state transitions: `UNKNOWN -> HEALTHY` is now immediate on first successful probe; only `UNHEALTHY -> HEALTHY` remains gated by `recovery_threshold` | Previously a fresh registry needed `recovery_threshold` consecutive successes before any replica was selectable. With default `recovery_threshold=2` and `health_check_interval=1s`, that meant 2-3s of `gpu_unavailable` rejections at startup. Now the first probe promotes immediately; recovery gating still protects against flapping replicas. |
| 3 | `router/registry.py::_build_default_probe` | Missing `httpx` now raises `RuntimeError` with install hint instead of yielding a "disabled" probe stub | Previous behavior: silently returned `(0.0, "httpx not installed; ...")` for every probe, which `record_failure` then folded into `UNHEALTHY` after `failure_threshold` cycles. Operators saw replicas drop UNHEALTHY with a confusing reason and no clear remediation. Hard-fail at startup is the right surface. |
| 4 | `router/config.py::__post_init__` | Extended D-15 polish #4 with: rejects `urlparse(url).path not in ("", "/")`, rejects `query`/`fragment`, rejects duplicate URLs across replicas | D-15's validation rejected non-`http(s)://` URLs and >1 primary; it didn't catch `http://host/api` (the router appends `/health` and `/v1/stream` itself, so a base-URL with path yields malformed routes) or `[{url: x}, {url: x}]` (replica registry keys by URL — duplicates would silently collapse to one entry, masking the misconfiguration). |
| 5 | `cli/router_serve.py::_load_router_config` | Replaced silent list-comprehension filter (`for r in replicas_raw if isinstance(r, dict) and r.get("url")`) with per-index `raise ValueError` | Original parser silently dropped malformed YAML entries. A single typo in `replicas[2].url` would yield 2 replicas instead of 3 with no log line. New shape: explicit per-index error message ("missing required key 'url'", "must be a mapping"). |
| 6 | `pyproject.toml::[streaming]` extra | Added `websockets` as explicit dep | `router/main.py::_bridge_session` does `import websockets` lazily and raises `RuntimeError` if missing. The `[streaming]` extra was an implicit transitive — anyone installing only `[streaming]` (and not the broader requirements) hit the runtime error. Now explicit. |
**Tests added (7 cases in `fastvideo/tests/entrypoints/streaming/test_router.py`):**
- `TestUnknownToHealthyImmediate.test_first_success_promotes_unknown` — first probe success transitions `UNKNOWN -> HEALTHY` regardless of `recovery_threshold`
- `TestUnknownToHealthyImmediate.test_unhealthy_recovery_still_gated_by_threshold` — `UNHEALTHY -> HEALTHY` still requires `recovery_threshold` successes
- `TestConfigValidation.test_rejects_path_in_url` / `test_rejects_query_in_url` / `test_rejects_fragment_in_url` / `test_rejects_duplicate_urls` / `test_accepts_trailing_slash` — `__post_init__` URL validation matrix
**Verification:** 17/17 router tests pass on both branches. `pre-commit run`
clean (yapf / ruff / codespell / mypy). `lsp_diagnostics` clean on changed
regions; the one pre-existing `Task` generic-type warning at `main.py:37` is
unrelated and predates this commit.
**In-flight pre-commit corrections (not part of the 6 fixes themselves):**
- yapf auto-reformatted 4 files (kept verbatim).
- ruff `UP038`: rewrote `isinstance(exc, (CancelledError, WebSocketDisconnect))`
to `isinstance(exc, CancelledError | WebSocketDisconnect)`.
- mypy `[misc]`: renamed loop var `exc` (inside `for task in done`) to
`task_exc` to avoid name collision with the outer
`except ImportError as exc` binding.
**Open thread it touches:** None new. Item #14 (bridge backpressure) and
item #13 (sticky routing) from D-15 remain deferred — this round addressed
**cancellation/disconnect** semantics on the bridge, which is distinct from
**throughput backpressure**. Item #14 still applies: at higher load, add
`_bridge_session()` max-size + timeout limits or recommend Envoy/HAProxy
in front.
### D-14: Streaming auxiliaries (PR #1284) — cohesion + concrete-vs-Protocol scoping
**Status:** ✅ Resolved (interim). Two polish items applied during review; one
operational caveat tracked.
**Source:** Oracle review on 2026-05-04, during PR #1284 review cycle.
**Question:** Is PR #1284's bundle of 4 streaming-server auxiliary modules
(`prompt/safety.py`, `prompt/rewrite.py`, `session_logger.py`,
`mock_server.py`) correctly scoped? Should `mock_server` live in production
module path? Should `PromptSafetyFilter` be a Protocol? Should the bundle
have been split into 4 PRs?
| Alt | Approach | Verdict |
|---|---|---|
| A | Status quo — single PR, 4 modules under `streaming/`, mock_server in production path, concrete safety filter | ✅ **Keep** |
| B | Split into 4 separate PRs | ❌ Process overhead, not architectural improvement |
| C | Move `mock_server.py` into `tests/` | ❌ Would reduce discoverability + install-time usability of `python -m fastvideo.entrypoints.streaming.mock_server` |
| D | Move `session_logger.py` to `streaming/observability/` (or top-level `fastvideo/observability/`) | ❌ Premature — currently session-shaped + streaming-specific; promote when a non-streaming consumer appears |
| E | Convert `PromptSafetyFilter` to Protocol (like `LLMProvider`) | ❌ Premature abstraction — only one classifier exists; small duck-typed surface preserves future Protocol introduction without breaking the concrete |
| F | Convert `MockGenerator` to Protocol | ❌ Same — small duck-typed surface; no second mock generator exists |
**Decision:** Alt A — keep current shape. Apply two polish items from
Oracle's review before merge.
**Rationale:**
- "Streaming-server auxiliaries" is cohesive enough at 730 LOC with
isolated modules + tests. Each module has independent code path but
shared deployment context (the streaming server boots them all).
- `mock_server.py` in production path is a strength: reuses
`build_app()` for protocol parity. Hiding it under `tests/` would lose
`python -m fastvideo.entrypoints.streaming.mock_server` CLI access for
FE devs.
- Concrete `PromptSafetyFilter` matches "ship what we have, abstract
later" pattern. Internal had multi-classifier composition; public
ships single + leaves chaining as a Dreamverse-side concern (per D-2).
- Same pattern for `MockGenerator`: small duck-typed `_GeneratorLike`
surface lets a second mock implementation drop in without inheritance.
- `threading.Lock` (not `asyncio.Lock`) in `session_logger.py` is
correct — writes come from real encoder/control threads via
`run_in_executor`, not from coroutines directly. `asyncio.Lock` would
be the wrong primitive for cross-thread concurrency.
**Pre-merge polishes applied (per Oracle):**
| Polish | What | Why |
|---|---|---|
| 1 | Removed `RewriteOptions.user_system_prompt_override` | Inert public field — was declared but never threaded through to `enhancer.rewrite()`. Shipping unused public options is more likely to bite than any structural choice. Re-add when actually wired through. |
| 2 | Sanitized `session_id` filename in `session_logger.SessionLogger._get_file()` | Defense-in-depth: today session_id is server-generated UUID, but a future code path that accepts client-supplied ids would otherwise allow path traversal via `../`. Added `_FILENAME_SANITIZE_RE = re.compile(r"[^A-Za-z0-9._-]")` + sub before `os.path.join`. |
**Operational caveat tracked (not a code change):**
- `SafetyDecision.UNAVAILABLE` is treated as `ALLOW` by callers — a
policy choice that's correct for an opt-in safety filter, but
callers should log loudly so operators know the filter is degraded.
Tracked as open-threads.md item #12.
**Pre-merge review feedback (4 of 4 resolved on the GitHub PR):**
| # | File:Line | Severity | Issue | Fix applied |
|---|---|---|---|---|
| 1 | `session_logger.py:57` | High | `log()` race vs `close()` — `KeyError` on `_locks[session_id]` | Atomic capture in `_get_file()`; master `_registry_lock`; `with lock, contextlib.suppress(ValueError):` |
| 2 | `rewrite.py:71` | Medium | `re.compile()` in hot path | Module-level `_LEADING_MARKER_RE`, top-level `import re` |
| 3 | `safety.py:105` | Medium | `_ensure_loaded()` race on concurrent fastText load | `_load_lock = threading.Lock()` + double-check pattern |
| 4 | `pyproject.toml:145` | Medium | `streaming` extra missing `prompt-safety` | Added to aggregator |
All 4 review threads marked resolved via GraphQL `resolveReviewThread`.
**Action items (deferred):**
- [ ] Track `SafetyDecision.UNAVAILABLE` log loudness in
open-threads.md item #12 — when streaming server starts using the
safety filter, ensure operator-visible logging on `UNAVAILABLE`
results
- [ ] If a second safety classifier appears (Perspective API, Detoxify,
custom rules), promote `PromptSafetyFilter` to a Protocol — same
pattern as `LLMProvider` per D-13
- [ ] If a second mock generator appears (different frame patterns,
different latency models), promote `MockGenerator` to a Protocol
**Open thread it touches:** PR #1284 itself; future safety-classifier
Protocol promotion; future observability module extraction.
### D-13: Prompt enhancer / `LLMProvider` abstraction shape — keep streaming-scoped
**Status:** ✅ Resolved (interim) + 🟡 Three deferred polishes after metrics or 2nd consumer.
**Source:** Oracle review on 2026-05-04, pre-PR-#1258-merge.
**Question:** Is PR #1258's `fastvideo.entrypoints.streaming.prompt.*` module
correctly designed? Should it be (a) Protocol-based vs ABC, (b) under
`streaming/` vs top-level `fastvideo.prompt.*`, (c) closed 3-op enum vs
open `complete()` API?
| Alt | Approach | Verdict |
|---|---|---|
| A | Status quo — `streaming/prompt/*`, Protocol provider, fixed 3 ops, lazy `httpx`, per-call `AsyncClient` | ✅ **Keep** |
| B | Move to top-level `fastvideo.prompt.*` (decouple from streaming) | ❌ **Premature.** No second consumer exists yet. |
| C | Convert `LLMProvider` Protocol → ABC with default impls + retry classification | ❌ **Wrong direction.** Biases extension toward OpenAI shape; `_openai_compat.py` already factors that as helper not inheritance. |
**Decision:** Alt A as interim. Promote to Alt B only when a second
non-streaming consumer (OpenAI server, batch generation, tooling) actually
needs the prompt enhancer. Don't pursue Alt C.
**Rationale:**
- Public contract is tiny — `name: str` + `async complete(LLMRequest) -> LLMResponse`. ABC adds zero value.
- `_openai_compat.py` is the right place for shared logic — helper, not base class. Anthropic / local / custom providers stay first-class.
- The 3 ops (enhance / auto_extend / rewrite) are LTX-2 streaming concepts. `auto_extend` (continue prompt sequence) and `rewrite` (multi-line alternatives) come directly from session UX. Calling this "the FastVideo prompt API" misrepresents that.
**Specific risks flagged in PR #1258 (already merged-pending review):**
| Risk | Mitigation (when relevant) |
|---|---|
| API publicity — calling this "the FastVideo prompt API" before a second consumer exists | Document module as "streaming-server prompt enhancement" in user-facing docs; keep it nested under `entrypoints/streaming/` |
| `httpx.AsyncClient` per-call (no connection pooling) | Acceptable for ~6-10 calls per LTX-2 session; LLM latency dominates. Add optional `client_factory` parameter LATER if metrics show connect overhead is meaningful. |
| 3 fixed operations could constrain future generic use | Closed enum is right for application-level orchestration. Future generic consumers should either call `provider.complete()` directly, or get a thin separate enhancer that shares the provider/fallback machinery. |
| `register_provider(priority=-1)` semantics rely on Python's negative-index `list.insert` | Cosmetic concern; docstring is clear. Could be tightened to explicit branch later. |
| `runtime_checkable` Protocol with `name: str` instance attribute — static type checkers may miss missing `name` | Acceptable; runtime check via `isinstance(p, LLMProvider)` works for plugin discovery. |
**Action items (deferred):**
- [ ] Document `fastvideo.entrypoints.streaming.prompt.*` as streaming-scoped in user-facing docs (PR 12 docs migration); avoid promoting as framework-level
- [ ] Add optional `client_factory` parameter to providers when metrics justify pooling
- [ ] Plan future move to `fastvideo.prompt.*` (with import shim) when second non-streaming consumer materializes
- [ ] Track Q-2 reactivation: promote LTX-2 prompt orchestration (locked segments, segment-prompts JSON parsing) to public `fastvideo.entrypoints.streaming.prompt.ltx2_orchestration` when a second LTX-2-style consumer appears
**Open thread it touches:** Dreamverse migration (open-threads.md DR-1)
will be the first real test of the public surface. Lessons learned there
inform whether Alt B becomes feasible.
## D-decisions (from `dreamverse_review.md`, Apr 26)
### D-1: Realtime runtime → streaming GpuPool migration shape
**Status:** ✅ Resolved.
Internal `RealtimeRuntimeConfig` had a multi-model registry +
flattened sampling defaults. Public `SubprocessGpuPool` is single-model
+ uses per-request `SamplingConfig`.
**Decision:** Drop multi-model registry on integration branch (not used
in production). Construct `GeneratorConfig` for chosen model and pass to
`SubprocessGpuPool`. Move sampling defaults to a server-side
`default_request: GenerationRequest` template.
**Risk:** Migration branch surfaces missing-model errors if a flow
silently relied on registry to swap models per-session. Integration
tests exercise at least one segment per supported model id before
merging.
### D-2: PR 7.7 prompt enhancer API surface narrower than internal
**Status:** ✅ Resolved.
Public `PromptEnhancer.enhance/auto_extend/rewrite` returns
`LLMResponse(content, provider, model, latency_ms, fallback_used)`.
Internal returns `EnhanceResult(prompt, fallback_used, error, ...)` /
`RewriteResult(prompts, ..., rollout_id, rollout_label, ...)`.
**Decision:** Adapt at the call site via
`Dreamverse/server/prompting/_internal_compat.py` shim. Locked-segment /
next-segment-index plumbing stays Dreamverse-side. Public stays minimal
and provider-agnostic.
**Open question (Q-2):** Promote LTX-2-specific orchestration into
`fastvideo.entrypoints.streaming.prompt.ltx2_orchestration` once a
second consumer appears. Logged for future review.
### D-3: Multi-stage provider race vs. sequential fallback
**Status:** ✅ Resolved (public stays sequential).
Internal enhancer runs all providers in a stage in parallel
(`_run_provider_race`). Public enhancer runs sequentially with
retryable-error fallback.
**Decision:** Public stays sequential for PR 7.7. Race is a
Dreamverse-specific tail-latency optimization that depends on parallel
API budgets.
**Risk / Q-3:** First-segment latency on Dreamverse may regress
slightly when Cerebras has a bad minute (sequential waits 20s before
trying Groq). If real production concern, add public
`concurrency: int = 1` knob behind a race path — but only after measuring.
### D-4: Skip PR 7.9 router for the integration branch
**Status:** ✅ Resolved.
Internal stack ships `router/main.py` for multi-replica load balancing.
Dreamverse deployment uses single replica per region.
**Decision:** Land PR 7.9 publicly (upstream the surface). Skip wiring
into Dreamverse integration branch. Dreamverse's `server/main.py` does
not import from `router/`.
### D-5: Audio re-encode (PR 7.10) needed for streaming, deferred
**Status:** 🟡 Deferred to PR 7.10.
Internal streaming server's per-step path runs `_re_encode_audio` inside
`_stream_av_fmp4_events` so each fMP4 segment ships with
continuation-conditioning audio. Whole-segment `pool.run()` path doesn't
need this.
**Decision:** Land PR 7.10's `generate_async` publicly. Dreamverse
integration branch initially keeps using `pool.run()` (whole segment, no
re-encode). Follow-up branch swaps to `generate_async` + audio re-encode.
**Open question (Q-5):** Acceptable for first switch, or does
Dreamverse audio quality regress vs. internal until 7.10 wires in?
### D-6: `realtime/local_runtime.py` is NOT upstreamed
**Status:** ✅ Resolved.
It was the FastVideo-internal precursor to `streaming.gpu_pool`.
Upstreaming both would create two GPU pool implementations in public.
**Decision:** Don't upstream `realtime/local_runtime.py`. Dreamverse
switches to `streaming.gpu_pool.SubprocessGpuPool` on integration
branch. Internal module can be deleted at follow-up.
### D-7 / Q-6: `FP4Config` is private-only
**Status:** ✅ **Resolved May 2.**
April 26: `Dreamverse/server/video_generation.py:271` imported
`fastvideo.layers.quantization.fp4_config.FP4Config` from
FastVideo-internal only. The 411-line module hard-imported `flashinfer`.
**Two options at the time:**
1. Colocate publicly with `flashinfer` as optional extra
`pip install fastvideo[fp4]`; refactor `FP4QuantizeMethod` to take
layer-prefix list from a pipeline-config field instead of hardcoding
ltx2 paths.
2. Keep private — Dreamverse imports from internal via thin shim.
**Recommendation at the time:** option 1 once API refactor settles.
**Resolution:** May 2 work chose option 1.
- `365a66c7` upstreamed FP4Config with lazy `flashinfer` import in
loader helper (no public hard-dep)
- `94c983a2` renamed FP4 → NVFP4 to disambiguate from MX-FP4 / OCP-FP4
- `42b30bf9` wired through `fastvideo.layers.quantization`
See [quantization.md](quantization.md) for full details.
### D-8: `ltx2_image_crf` silently dropped by public schema
**Status:** 🔴 **Unverified post-`d80c2a8`.**
April 26: Dreamverse's `server/video_generation.py:406` passed
`ltx2_image_crf=0.0` to `SamplingParam(...)`. Public
`fastvideo.api.sampling_param.SamplingParam` did NOT have this field;
the BE logged ERROR and silently dropped the kwarg.
**Migration target** (per [design.md](design.md) compatibility map):
`request.stage_overrides.refine.image_crf`.
**Resolution status:** `d80c2a8` (May 2) refactored
`server/video_generation.py` to use typed `GeneratorConfig` +
`preset_overrides["refine"]`. Whether this PR routed `image_crf`
through the typed `stage_overrides` path or left it silently dropped is
unverified. See [open-threads.md](open-threads.md).
### D-9: `aarch64-conda-linux-gnu-cc` triton compile failure
**Status:** ✅ Resolved (operational).
Conda env injected an ARM cross-compiler ahead of `gcc` on `$PATH`, so
`torch._inductor`'s triton launcher failed compilation. Setting
`ENABLE_TORCH_COMPILE=0` bypasses it.
**Long-term fix:** clean conda env's compiler shadowing or add
`CC=gcc` override in Dreamverse's worker bootstrap.
### D-10: Warmup OOM on shared GPU
**Status:** ✅ Resolved (operational).
When `CUDA_VISIBLE_DEVICES` lands on a GPU another tenant uses, LTX-2
warmup fails with OOM. Picking an idle GPU (4-7 in test setup) is a
manual step.
**Improvement:** pre-warm probe that checks free memory before booting
the pool would prevent this.
### D-11: ffmpeg fragment write `Broken pipe`
**Status:** ✅ Resolved (cosmetic).
When WS client closes before backend finishes streaming first segment,
ffmpeg hits `[Errno 32] Broken pipe`. Currently propagates to
"User step failed". Cosmetic — swallowing pipe-broken on intentional
disconnect would clean up logs.
## Q-questions (from `streaming-server-upstream-plan.md`, Apr 17)
### Q-1: Router placement (in-repo or separate package)
**Status:** ✅ Resolved (in-tree).
**Recommendation at the time:** separate package `fastvideo-router/` or
`fastvideo/contrib/router/`; defer final call to PR 7.9.
**Resolution:** PR 7.9 implementation places router in-tree at
`fastvideo/entrypoints/streaming/router/`.
### Q-2: Session ID authority
**Status:** ✅ Resolved (server-generated).
**Recommendation:** server-generated UUID; accept externally provided
session ID only for resume flows.
### Q-3: Torch compile kwargs typing (opaque vs full vs hybrid)
**Status:** ✅ Resolved (hybrid).
**Recommendation:** hybrid — type the common four (`backend`,
`fullgraph`, `mode`, `dynamic`) + allow `extras: dict[str, Any]`.
**Resolution:** PR 6 + NVFP4 `221cb20a` shipped exactly this hybrid.
### Q-4: Prompt safety / fasttext dependency
**Status:** ✅ Resolved (optional extra).
**Recommendation:** ship as optional extra `pip install fastvideo[prompt-safety]`.
**Resolution:** PR 7.8 implements as optional extra.
### Q-5: Audio-specific tensor payloads in continuation
**Status:** ✅ Resolved (typed `LTX2ContinuationState`).
`ltx2_audio_clean_latent`, `ltx2_audio_denoise_mask`,
`ltx2_audio_latents` not in pre-refactor public schema.
**Recommendation:** classify as opaque fields inside
`LTX2ContinuationState.payload`, not top-level sampling fields.
**Resolution:** PR 7's typed `LTX2ContinuationState` lifts these into
typed fields (see [cross-repo-surfaces.md](cross-repo-surfaces.md)
field mapping table).
### Q-6: Dynamo subpackage home
**Status:** ✅ Resolved (lives in Dynamo repo).
**Resolution:** No Dynamo code in FastVideo. Full backend package
(handler, adapter, registration, health check) owned by Dynamo repo at
`components/src/dynamo/fastvideo/`, same pattern as vllm/sglang.
FastVideo only guarantees the public API contract.
### Q-7 (was Q-6 in dreamverse_review): How to land FP4Config publicly
**Status:** ✅ Resolved May 2 — option 1 (colocate publicly).
See D-7 above.
### Q-8: Disaggregation readiness contract test
**Status:** 🟡 Recommended; not yet shipped.
PR ai-dynamo/dynamo#7544 is aggregated-only. `ContinuationState` hybrid
already supports future prefill/decode split.
**Recommendation:** PR 7.10 explicitly validate `ContinuationState`
survives round-trip through Dynamo-style RPC (pickle or JSON), even
though Dynamo isn't using it today. Cheap regression guard.
### Q-9: Dynamo progress/status passthrough
**Status:** 🟡 Deferred until Dynamo clarifies.
`NvVideosResponse` has `status` and `progress` fields.
**Recommendation:** PR 7.10 stays aggregated-final-only to match PR
#7544 shape; revisit after Dynamo clarifies their streaming/progress
semantics.
## Cross-doc questions still 🔴 OPEN
These need decisions; tracked also in [open-threads.md](open-threads.md):
| ID | Question | Source | Why it matters |
|---|---|---|---|
| **D-8** | Did `d80c2a8` route `ltx2_image_crf` correctly, or is it still silently dropped? | dreamverse_review | Latent silent-drop bug; FP4-disabled paths may degrade |
| **VPO** | `video_position_offset_sec` — persistent accumulation (a) vs per-segment hint (b) | dreamverse_integration | Needs decision before PR 7.6 emits state |
| **SBS** | `SessionStore` / `BlobStore` lifecycle (TTL/eviction/blob-drop on state replacement) | dreamverse_integration | Needs decision in PR 7.5 design pass |
| **#1** | Migrate `/healthz`+`/readyz`+`/status` into FastVideo `build_app` | streaming-upstream-plan + handoff | Closes BE_FLAVOR=fastvideo FE-compatibility |
| **#3** | Add `cerebras_ifm` to public `PromptEnhancerConfig.provider` Literal | handoff | Internal supports it; public schema doesn't |
| **#4** | Expose `layer_profile` on typed `engine.quantization` | handoff | Removes Dreamverse's `experimental["pipeline_config"]` dodge |
| **#5** | Typed `dit_config.quant_config` carrier (design TBD) | handoff | Eliminates the `experimental["pipeline_config"]` escape hatch entirely |
@@ -1,332 +0,0 @@
# Design — Typed Public Inference API
Synthesis of the FastVideo public inference API refactor design philosophy.
For PR-by-PR execution see [pr-roadmap.md](pr-roadmap.md). For the streaming
extension see [streaming-server.md](streaming-server.md).
**Last updated:** 2026-05-03.
## Why the refactor
The pre-refactor public boundary mixed three concerns through `**kwargs`:
- `VideoGenerator.from_pretrained(..., **kwargs)` mixed engine/runtime,
pipeline init, and component overrides.
- `VideoGenerator.generate_video(..., **kwargs)` mixed prompt+inputs,
sampling, output, and model-specific workflow knobs.
- Unknown keys silently filtered or merely logged → API drift hard to detect.
- Multi-stage models (LTX-2 two-stage, Hunyuan15 SR, LongCat distill+refine)
exposed via ad hoc top-level flags.
This was already painful for LTX2/Dreamverse and would worsen as more
multi-stage pipelines came in.
## Core decision
FastVideo has:
1. **Typed nested public schema** — `RunConfig`, `ServeConfig`,
`GeneratorConfig`, `GenerationRequest`, `ContinuationState`.
2. **Model-owned named pipeline presets** — `ltx2_two_stage`,
`longcat_distill_refine`, `hunyuan15_sr_1080p`, etc. All 13 model families
landed presets in PR 4.
3. **Semantic stage overrides by stage name** —
`request.stage_overrides["refine"] = LTX2RefineStageOverride(...)`.
4. **Optional advanced explicit plans** for power users — `GenerationPlan`
(escape hatch only; not the canonical surface).
5. **YAML-first CLI** with dotted overrides —
`fastvideo generate --config run.yaml --request.sampling.seed 42`.
The canonical user experience: choose a model → choose a preset → override
a few typed fields → generate. Dicts/YAML/JSON are supported as
serialization, but parse immediately into typed objects with strict
unknown-key validation.
## Schema surface
Implemented in [`fastvideo/api/`](file:///home/william5lin/FastVideo/fastvideo/api/):
| Type | Role |
|---|---|
| `RunConfig` | Offline envelope: `generator` + `request` |
| `ServeConfig` | Serving envelope: `generator` + `server` + `default_request` + optional `streaming` |
| `GeneratorConfig` | `model_path`, `revision`, `trust_remote_code`, `engine`, `pipeline` |
| `EngineConfig` | parallelism / offload / compile / quantization / flags |
| `PipelineSelection` | `workload_type`, `preset`, `preset_version`, `components`, `preset_overrides`, `experimental` |
| `GenerationRequest` | `prompt`, `negative_prompt`, `inputs`, `sampling`, `runtime`, `output`, `stage_overrides`, `state`, `plan`, `extensions` |
| `ContinuationState` | Opaque envelope `{kind: str, payload: dict[str, Any]}` |
| `GenerationPlan` | Advanced/escape-hatch only; `{stages: list[PlannedStage], final_stage: str|None}` |
Files:
| File | Role |
|---|---|
| [`schema.py`](file:///home/william5lin/FastVideo/fastvideo/api/schema.py) | All public dataclasses |
| [`parser.py`](file:///home/william5lin/FastVideo/fastvideo/api/parser.py) | `from_dict`, `to_dict`, `load_yaml`, `load_json`, validation |
| [`overrides.py`](file:///home/william5lin/FastVideo/fastvideo/api/overrides.py) | Dotted override application |
| [`compat.py`](file:///home/william5lin/FastVideo/fastvideo/api/compat.py) | Legacy kwargs translation (~370 lines, scheduled for death PRs 14-17) |
| [`presets.py`](file:///home/william5lin/FastVideo/fastvideo/api/presets.py) | Preset registry |
| [`sampling_param.py`](file:///home/william5lin/FastVideo/fastvideo/api/sampling_param.py) | Internal `SamplingParam` adapter (canonical home since PR 4) |
| [`results.py`](file:///home/william5lin/FastVideo/fastvideo/api/results.py) | `GenerationResult` / `VideoResult` |
| [`errors.py`](file:///home/william5lin/FastVideo/fastvideo/api/errors.py) | Path-aware validation errors |
## Boundary normalization rule
Every public inference entrypoint normalizes into typed config objects
before touching legacy internals (`FastVideoArgs`, `SamplingParam`).
Includes Python constructors, `generate*` calls, CLI `generate`, CLI
`serve`, OpenAI server request translation, streaming server request
translation.
Legacy internals (`FastVideoArgs`, `SamplingParam`) may remain temporarily,
but only behind a typed normalization boundary.
## Strict-by-default validation
All structured inputs are strict:
- Unknown keys → error
- Wrong types → error
- Invalid stage names → error
- Incompatible state/preset combinations → error
The only intentional escape hatches:
- `generator.pipeline.experimental` — for in-flight features without typed home
- `request.extensions` — same, request-side
These bypass validation by design. Intent: shrink as presets absorb
model-specific fields. New fields should not land in `experimental` /
`extensions` without a plan to either promote them to typed fields or
remove them within two PR cycles.
Error format includes nested path:
```
Invalid field: request.stage_overrides.refine.num_inference_steps
Expected int, got "two"
Preset: ltx2_two_stage
Stage: refine
```
## Request mutation tracking
When a `GenerationRequest` is parsed from raw dict (YAML/JSON/Python),
FastVideo tracks which fields the user explicitly provided vs. which got
schema defaults. Matters for `request_to_sampling_param()` — explicit
values override model defaults; schema defaults do NOT.
Mechanics:
- At parse time, original raw dict + baseline snapshot stored on the request.
- Dataclass field mutations (e.g. `request.sampling.seed = 7`) captured via
lightweight `__setattr__` dirty-path recording.
- Dict-typed field mutations (e.g. `del request.stage_overrides["refine"]`)
detected at access time by diffing current dict vs. baseline.
- Setting a field to its schema default value IS captured as explicit, so
it overrides model defaults.
- Raw dict reconciled lazily when `normalize_generation_request()` is called.
## Schema purity (model-specific fields still in shared schema)
Remain for back-compat during initial migration; targeted for migration
into preset-owned typed override classes:
| Field | Owner | Migration target |
|---|---|---|
| `SamplingConfig.height_sr` / `width_sr` / `num_inference_steps_sr` | Hunyuan15 SR | `HunyuanSRStageOverride` (PR 10) |
| `SamplingConfig.guidance_scale_2`, `boundary_ratio` | Wan2.2, LingBotWorld | preset-owned (per-family PR) |
| `InputConfig.mouse_cond`, `keyboard_cond`, `grid_sizes` | MatrixGame | `request.extensions` or typed input config |
| `InputConfig.c2ws_plucker_emb` | LingBotWorld | `request.extensions` or typed input config |
| `InputConfig.refine_from`, `stage1_video` | LongCat | `LongCatRefineStageOverride` inputs (PR 9) |
LTX-2 multi-modal CFG knobs (`ltx2_modality_scale_video/_audio`,
`ltx2_rescale_scale`, `ltx2_stg_scale_video/_audio`,
`ltx2_stg_blocks_video/_audio`) still leak into shared `SamplingParam` but
only LTX-2 reads them today. Migration to typed `LTX2SamplingOverride` is
deferred to per-model migration sweep.
**LTX-2 CFG-force fix landed in PR 6**: defaults moved from `3.0/7.0` to
`1.0/1.0` to stop force-enabling CFG for non-LTX-2 families.
`ltx2_base` preset still sets `3.0/7.0` explicitly. Regression guard:
`test_presets.py::TestPresetDefaultTypes::test_ltx2_cfg_defaults_are_off`.
## Continuation state
Public surface:
```python
@dataclass
class ContinuationState:
kind: str # e.g. "ltx2.v1"
payload: dict[str, Any]
```
Internally, model-specific typed subclasses (e.g. `LTX2ContinuationState`
at [`fastvideo/pipelines/basic/ltx2/continuation.py`](file:///home/william5lin/FastVideo/fastvideo/pipelines/basic/ltx2/continuation.py)).
Payload must be JSON-serializable or use opaque blob-ID indirection for
large tensors — supports both stateless OpenAI client round-trip AND
future Dynamo prefill/decode disaggregation.
Hybrid model: server-held for streaming WS, client-round-trip for
stateless HTTP. See [streaming-server.md](streaming-server.md) D-1.
## Pipeline package structure (target)
Per-family colocation under `pipelines/basic/<family>/`:
```
fastvideo/pipelines/basic/<family>/
├── <family>_pipeline.py # pipeline implementation(s)
├── presets.py # user-facing presets (DONE in PR 4)
├── pipeline_configs.py # engine/arch config (from configs/pipelines/)
└── stages/ # model-specific stages (optional, if >2 files)
```
What stays shared:
- `configs/pipelines/base.py` — `PipelineConfig` base class
- `configs/models/` — architecture defs (dits/, vaes/, encoders/)
- `pipelines/stages/` — shared stages only (denoising, encoding, decoding,
text_encoding, timestep_preparation, ...)
What's gone (PR 4):
- `fastvideo/configs/sample/` — directory removed entirely; defaults
absorbed into per-family `presets.py`.
- All 12 `*_SamplingParam` subclass files — `SamplingParam` lives at
`fastvideo/api/sampling_param.py`; defaults flow through
`SamplingParam.from_pretrained()` → `_from_preset()`.
What's pending: `configs/pipelines/<family>.py` colocation, optional
`pipelines/stages/<family>_*.py` colocation. Per-model migration PRs
(6/9/10) include the colocation step for that family.
## YAML examples
### Run config
```yaml
generator:
model_path: /models/ltx2
engine:
num_gpus: 1
parallelism: {tp_size: -1, sp_size: -1}
offload: {dit: false, text_encoder: false, vae: false, pin_cpu_memory: true}
pipeline:
workload_type: t2v
preset: ltx2_two_stage
components:
config_root: /models/ltx2-config
upsampler_weights: /models/ltx2-refine
lora_path: /models/ltx2-refine-lora
preset_overrides:
refine: {enabled: true, add_noise: true}
request:
prompt: "a fox running through snow"
sampling: {num_frames: 121, height: 1024, width: 1536, num_inference_steps: 8, seed: 42}
output: {save_video: true, return_state: true}
stage_overrides:
refine: {num_inference_steps: 2, guidance_scale: 1.0}
```
### Serve config
See [`Dreamverse/serve_configs/streaming_demo.yaml`](file:///home/william5lin/Dreamverse/serve_configs/streaming_demo.yaml)
for a canonical example matching internal/ui defaults (LTX-2 distilled,
NVFP4, 121 frames @ 1088×1920 24fps, 5 inference steps, 2-step refine).
## Compatibility mapping (legacy → typed)
| Legacy field | New path |
|---|---|
| `model_path` | `generator.model_path` |
| `num_gpus` | `generator.engine.num_gpus` |
| `tp_size` / `sp_size` | `generator.engine.parallelism.{tp_size,sp_size}` |
| `dit_cpu_offload` | `generator.engine.offload.dit` |
| `enable_torch_compile` | `generator.engine.compile.enabled` |
| `torch_compile_kwargs` | split: `generator.engine.compile.{backend,fullgraph,mode,dynamic}` + `.extras` |
| `enable_torch_compile_text_encoder` | `generator.engine.compile.text_encoder_enabled` |
| `prompt_txt` | `request.inputs.prompt_path` |
| `image_path` / `video_path` | `request.inputs.{image_path,video_path}` |
| `output_path` / `save_video` / `return_frames` | `request.output.*` |
| `seed` / `num_frames` / `height` / `width` / `fps` / `num_inference_steps` / `guidance_scale` | `request.sampling.*` |
| `enable_teacache` / `return_trajectory_*` | `request.runtime.*` |
LTX-2 specific (private adapter, NOT public compat promise):
| Legacy LTX-2 field | New path |
|---|---|
| `config_model_path` | `generator.pipeline.components.config_root` |
| `ltx2_refine_enabled` | `generator.pipeline.preset_overrides.refine.enabled` |
| `ltx2_refine_upsampler_path` | `generator.pipeline.components.upsampler_weights` |
| `ltx2_refine_lora_path` | `generator.pipeline.components.lora_path` |
| `ltx2_refine_num_inference_steps` | `request.stage_overrides.refine.num_inference_steps` |
| `ltx2_refine_guidance_scale` | `request.stage_overrides.refine.guidance_scale` |
| `ltx2_refine_add_noise` | `generator.pipeline.preset_overrides.refine.add_noise` |
| `ltx2_image_crf` | `request.stage_overrides.refine.image_crf` |
| `return_continuation_state` | `request.output.return_state` |
LongCat:
| Legacy | New |
|---|---|
| `refine_from` / `stage1_video` | `request.inputs.{refine_from,stage1_video}` |
| `t_thresh` / `spatial_refine_only` / `num_cond_frames` | `request.stage_overrides.refine.*` |
## External inspirations (and limits)
| Source | Useful idea | Don't copy |
|---|---|---|
| Ray | YAML-first config interchange | Ray's package layout |
| SGL `multimodal_gen` | Split instance/request config; dict input parsed into typed objects; merge user overrides on model defaults | `SamplingParams._adjust(ServerArgs)` (request depending on engine config); broad weakly-typed request bags |
| vLLM-Omni | Model-owned pipeline presets; explicit stage topology; per-stage default sampling | Positional `sampling_params_list`; serving-engine stage-index semantics in primary Python API |
## Naming guidance
- Public schema names namespaced under `fastvideo.api`
- Don't export from top-level `fastvideo/__init__.py` until migration further along
- `RunConfig` / `ServeConfig` get sufficient disambiguation from training
config via the namespace
- Future rename to `EngineQuantizationConfig` reserved if a collision
arises (deferred)
## Public Python API (canonical form)
```python
from fastvideo import VideoGenerator
from fastvideo.api import (
GeneratorConfig, GenerationRequest,
EngineConfig, OutputConfig,
PipelineSelection, SamplingConfig,
)
generator = VideoGenerator.from_pretrained(
config=GeneratorConfig(
model_path="/models/ltx2",
engine=EngineConfig(num_gpus=1),
pipeline=PipelineSelection(workload_type="t2v", preset="ltx2_two_stage"),
)
)
result = generator.generate(
GenerationRequest(
prompt="a fox running through snow",
sampling=SamplingConfig(num_frames=121, height=1024, width=1536,
num_inference_steps=8, seed=42),
output=OutputConfig(save_video=True, return_state=True),
)
)
```
Accepted constructor forms:
```python
VideoGenerator.from_pretrained(config=GeneratorConfig(...))
VideoGenerator.from_config(GeneratorConfig(...))
VideoGenerator.from_file("run.yaml")
VideoGenerator.from_pretrained("model-id", num_gpus=2, ...) # stable convenience
VideoGenerator.from_pretrained(model_path, **legacy_kwargs) # compat (deprecated PR 13)
```
File diff suppressed because it is too large Load Diff
@@ -1,888 +0,0 @@
# Integration Review — Drift Audit + Path Forward
> # ⚠️ DEPRECATED — superseded by [integration-plan.md](integration-plan.md)
>
> This document recommended **Option D** (Dreamverse stays a separate repo;
> generic backend merges into FastVideo). On 2026-05-05 the team chose
> **Option B+** instead (Dreamverse FE + product server move into FastVideo
> as `apps/dreamverse/`; generic backend stays at
> `fastvideo.entrypoints.streaming.*` per Option D's principle).
> See [decisions-log.md D-18](decisions-log.md#d-18) for the strategy
> reversal rationale and [integration-plan.md](integration-plan.md) for the
> executable migration plan.
>
> **What's still authoritative in this file:**
> - **Part 1 — Drift audit** (the 17-row drift summary table). The drift
> findings remain valid; the migration plan in `integration-plan.md`
> folds them into specific phases.
> - **OSS precedent citations** (vLLM, BentoML, Ray Serve, TGI+ChatUI,
> Transformers.js, ComfyUI, AUTOMATIC1111). Reused in `integration-plan.md`.
>
> **What's superseded:**
> - **Part 2 — Recommendation (Option D)**. Replaced by Option B+ in the
> new plan. Read `integration-plan.md` for the current decision.
> - **Part 3 — Action items**. Replaced by the phased migration plan.
>
> Kept in tree for historical reference and audit trail. Do not delete.
**Last updated:** 2026-05-05 (deprecated header added).
**Scope:** FastVideo public `will/ltx2_sr_port` at the requested audit
anchor `b36bdbc9`; Dreamverse `will/integrate-public-fastvideo` at
`ec8ef92`; FastVideo-internal `will/rebase-nbv` as read-only comparison.
**Memory-dir context:** the current integration memory snapshot tracks the
same public mega-PR lineage as `will/ltx2_sr_port`, with PRs #1257,
#1258, #1284, and #1286 already merged, #1287 closed, and #1288 open as
the consolidated landing vehicle for LTX-2 SR runtime, NVFP4,
`generate_async`, Dynamo contract, and memory-dir cleanup. Source:
[memory index](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/README.md#L8-L19)
and [D-17](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/decisions-log.md#L19-L45).
**Bottom line:** Zero core typed API drift — typed construction, typed
continuation state, NVFP4 wiring, and Dynamo-facing async events are either
already public or in #1288. **Real drift remains on the realtime-runtime
contract surface (`/healthz` / `/readyz` / `/status` routes per
[cross-repo-surfaces.md](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/cross-repo-surfaces.md#L74-L88))
and on operational/product edges**: stale Dreamverse docs/scripts, a
1933-LOC Dreamverse prompt-enhancer fork, two unresolved per-session
fields (`ltx2_image_crf` D-8, `video_position_offset_sec` VPO), one
missing example config, and two internal-only utilities whose product
relevance is not yet proven.
---
## Part 1 — Drift audit
### Methodology
1. **Compared three repositories and branches.**
- FastVideo public: `/home/william5lin/FastVideo`, branch
`will/ltx2_sr_port`.
- Dreamverse: `/home/william5lin/Dreamverse`, branch
`will/integrate-public-fastvideo`.
- FastVideo-internal: `/home/william5lin/FastVideo-internal`, branch
`will/rebase-nbv`.
- Canonical repo paths are listed in the integration memory index:
[repo paths](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/README.md#L72-L79).
2. **Scoped the audit to the ultimate integration goal.**
- Dreamverse should depend on public `fastvideo`, not
`FastVideo-internal`.
- FastVideo should own the reusable backend subset that Dreamverse
currently needs from internal: streaming runtime, GPU pool, router,
prompt enhancer, NVFP4, continuation state, and typed generation.
- Dynamo should consume FastVideo through typed public Python APIs, not
through private modules.
- The three Dreamverse surfaces are documented as pipeline construction,
realtime runtime, and continuation state:
[cross-repo surfaces](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/cross-repo-surfaces.md#L13-L20).
3. **Separated intentional refactor from drift.**
- A path rename is not drift if the public branch contains the same
responsibility under the typed design.
- A deleted file is not drift if the public design intentionally
consolidated it.
- A private alias is not drift if the public schema exposes a typed
replacement with contract tests.
- This matches the typed-public-boundary rule in
[design.md](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/design.md#L24-L43).
4. **Used memory docs for rationale and worktree files for concrete proof.**
- API schema and public exports:
[schema](file:///home/william5lin/FastVideo/fastvideo/api/schema.py#L68-L85),
[api exports](file:///home/william5lin/FastVideo/fastvideo/api/__init__.py#L49-L109).
- Streaming server current routes:
[build_app](file:///home/william5lin/FastVideo/fastvideo/entrypoints/streaming/server.py#L88-L160).
- Dreamverse dependency state:
[pyproject server extra](file:///home/william5lin/Dreamverse/pyproject.toml#L17-L22),
[uv lock editable source](file:///home/william5lin/Dreamverse/uv.lock#L716-L722).
- Contract tests:
[Dreamverse shape](file:///home/william5lin/FastVideo/fastvideo/tests/contract/test_dreamverse_shape.py#L1-L26),
[Dynamo shape](file:///home/william5lin/FastVideo/fastvideo/tests/contract/test_dynamo_shape.py#L1-L19),
[generate_async](file:///home/william5lin/FastVideo/fastvideo/tests/contract/test_generate_async.py#L1-L7).
5. **Did not treat product-only Dreamverse behavior as FastVideo drift.**
- Dreamverse keeps a local product server and Next.js UI today:
[README baseline](file:///home/william5lin/Dreamverse/README.md#L5-L16).
- Product-only routes, curated presets, devtools, and frontend-specific
behavior belong in Dreamverse unless a second non-Dreamverse consumer
needs them.
6. **Risk scale used below.**
- **P0:** blocks Dreamverse from running without FastVideo-internal.
- **P1:** blocks clean `BE_FLAVOR=fastvideo` or Dynamo/public API use.
- **P2:** reproducibility or maintenance drag.
- **P3:** optional parity or future memory/perf improvement.
### Findings: zero core typed API drift
The public branch is aligned with the goal on the **core typed API
surface** (construction, request, continuation state, async events).
The table below lists items that look like drift only if compared by
path name or legacy field name. They are intentional public refactors
or already guarded by tests. **Note:** the realtime-runtime _contract_
surface (FE-required health routes) is a separate matter — see "real
drift items" §4 below.
| Investigated item | Drift? | Evidence | Conclusion |
|---|---:|---|---|
| Dreamverse surface 1: pipeline construction | No | Dreamverse migrated from flat kwargs to typed `GeneratorConfig` at `d80c2a8`; mapping documented in [cross-repo surfaces](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/cross-repo-surfaces.md#L22-L47). | Stable public surface exists. |
| Dreamverse surface 2: realtime runtime | No on architecture; some route work remains | Runtime migration target is public `streaming/`, not internal `realtime/`: [streaming upstream](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/streaming-server.md#L14-L31). | Rename/refactor is intentional. |
| Dreamverse surface 3: continuation state | No | Public typed `ContinuationState` plus LTX-2 state mapping are documented in [cross-repo surfaces](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/cross-repo-surfaces.md#L108-L146). | Public state is a superset of Dreamverse's data carrier. |
| Internal `fastvideo/entrypoints/realtime/` | No | Public design chooses parallel `fastvideo/entrypoints/streaming/`: [layout decision](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/streaming-server.md#L55-L60), [current build_app](file:///home/william5lin/FastVideo/fastvideo/entrypoints/streaming/server.py#L88-L160). | Intentional rename plus typed-config rewrite. |
| Internal `configs/sample/` presets | No | Public PR 4 intentionally deleted `configs/sample/` and moved defaults to per-family presets plus `fastvideo/api/sampling_param.py`: [design](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/design.md#L194-L205), [PR roadmap](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/pr-roadmap.md#L21-L29). | Intentional consolidation. |
| LTX-2 pipeline presets | No | Public target is model-owned named presets and per-family colocation: [design](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/design.md#L175-L205). | Public layout matches design. |
| Internal `use_fp4_linear` flag | No | Public typed quant carrier is `engine.quantization.transformer_quant`; schema field exists in [schema](file:///home/william5lin/FastVideo/fastvideo/api/schema.py#L68-L85), compat resolves it in [compat.py](file:///home/william5lin/FastVideo/fastvideo/api/compat.py#L267-L279). | Replaced by typed NVFP4 surface. |
| Public-only `transformer_quant` field | No | Public `FastVideoArgs` pins typed quant to `dit_config.quant_config`: [fastvideo_args](file:///home/william5lin/FastVideo/fastvideo/fastvideo_args.py#L220-L228), [apply logic](file:///home/william5lin/FastVideo/fastvideo/fastvideo_args.py#L260-L279). | Public superset, not drift. |
| Internal `config_model_path` | No | Public typed home is `generator.pipeline.components.config_root`: [design mapping](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/design.md#L261-L269), [compat mapping](file:///home/william5lin/FastVideo/fastvideo/api/compat.py#L295-L299). | Alias is covered. |
| Internal flat video request fields | No | Public `GenerationRequest` nests `inputs`, `sampling`, `runtime`, `output`, `state`, `extensions`: [schema](file:///home/william5lin/FastVideo/fastvideo/api/schema.py#L193-L204). Internal legacy fields live in internal protocol at [protocol.py](file:///home/william5lin/FastVideo-internal/fastvideo/entrypoints/openai/protocol.py#L64-L82). | Intentional request refactor. |
| Dreamverse typed init kwargs | No | Contract test asserts current Dreamverse load kwargs all land on typed fields, not `experimental`: [test_dreamverse_shape](file:///home/william5lin/FastVideo/fastvideo/tests/contract/test_dreamverse_shape.py#L44-L135). | Guard in place. |
| Dreamverse request path | No | Contract test asserts request fields round-trip through typed `GenerationRequest`: [test_dreamverse_shape](file:///home/william5lin/FastVideo/fastvideo/tests/contract/test_dreamverse_shape.py#L153-L197). | Guard in place. |
| Dynamo native backend shape | No | FastVideo's only obligation is stable typed Python API: [cross-repo contract](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/cross-repo-surfaces.md#L188-L210). | Dynamo should stay out of FastVideo. |
| `generate_async` event API | No | API exists in [video_generator](file:///home/william5lin/FastVideo/fastvideo/entrypoints/video_generator.py#L264-L332), event types exist in [results.py](file:///home/william5lin/FastVideo/fastvideo/api/results.py#L109-L164). | #1288 covers the async contract. |
| Dynamo request mapping | No | Authoritative source is the contract test [test_dynamo_shape](file:///home/william5lin/FastVideo/fastvideo/tests/contract/test_dynamo_shape.py#L90-L175) which asserts `req.prompt`, `req.sampling.{height,width,num_frames,fps,num_inference_steps,guidance_scale,seed,negative_prompt}`, and `req.inputs.{image_path,video_path}` against the actual nested [`GenerationRequest` schema](file:///home/william5lin/FastVideo/fastvideo/api/schema.py#L193-L204). The `streaming-server.md` Dynamo mapping table mis-cites a `prompt -> sampling.prompt` path that no longer exists; the test is correct, the doc is stale and tracked for refresh. | Guard in place; companion doc needs minor refresh. |
| Public API exports | No | `VideoEvent`, `VideoResult`, and typed schema classes are exported from [fastvideo.api](file:///home/william5lin/FastVideo/fastvideo/api/__init__.py#L49-L109). | Integration imports resolve. |
| FastVideo-internal FP4/NVFP4 paths | No | Public NVFP4 files and roles are documented in [quantization](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/quantization.md#L24-L35); actual `NVFP4Config` documents lazy FlashInfer and public naming in [nvfp4_config.py](file:///home/william5lin/FastVideo/fastvideo/layers/quantization/nvfp4_config.py#L1-L19). | Public is typed superset. |
| AbsMaxFP8 refactor | No for Dreamverse | Public quant registry includes `AbsMaxFP8` and `NVFP4`: [quantization init](file:///home/william5lin/FastVideo/fastvideo/layers/quantization/__init__.py#L1-L8). AbsMaxFP8 failure is tracked as separate tech debt: [open threads](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/open-threads.md#L100-L117). | Not Dreamverse blocker. |
| Internal realtime API regression test | No | Public contract tests replace it: [Dreamverse contract](file:///home/william5lin/FastVideo/fastvideo/tests/contract/test_dreamverse_shape.py#L1-L26), [Dynamo contract](file:///home/william5lin/FastVideo/fastvideo/tests/contract/test_dynamo_shape.py#L1-L19), [generate_async tests](file:///home/william5lin/FastVideo/fastvideo/tests/contract/test_generate_async.py#L91-L230). | Better scoped guards exist. |
| Dreamverse dependency declaration | No | `server` extra declares `fastvideo>=0.1.7`: [pyproject](file:///home/william5lin/Dreamverse/pyproject.toml#L17-L22). Dev lock resolves editable public `../FastVideo`: [uv.lock](file:///home/william5lin/Dreamverse/uv.lock#L716-L722), [package source](file:///home/william5lin/Dreamverse/uv.lock#L777-L780). | Dependency is already switched in metadata/lock. |
#### Core conclusion for the zero-typed-drift section
The public typed API no longer needs to mirror `FastVideo-internal` file
paths. The correct test is whether Dreamverse and Dynamo can express their
needs through public typed objects and public entrypoints. On that test,
the **typed core** is covered (construction, request, continuation,
async events). The **runtime contract** still has health-route gaps —
see real drift §4. On the **typed core**:
- `GeneratorConfig` and `GenerationRequest` cover construction and calls:
[schema surface](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/design.md#L45-L72).
- `ServeConfig.streaming` covers the server envelope:
[schema](file:///home/william5lin/FastVideo/fastvideo/api/schema.py#L244-L279).
- `generate_async` covers streaming, OpenAI, and Dynamo on one substrate:
[video_generator](file:///home/william5lin/FastVideo/fastvideo/entrypoints/video_generator.py#L264-L332).
- Contract tests now encode the cross-repo shapes:
[Dreamverse](file:///home/william5lin/FastVideo/fastvideo/tests/contract/test_dreamverse_shape.py#L70-L214),
[Dynamo](file:///home/william5lin/FastVideo/fastvideo/tests/contract/test_dynamo_shape.py#L170-L331),
[async events](file:///home/william5lin/FastVideo/fastvideo/tests/contract/test_generate_async.py#L91-L273).
### Findings: real drift items requiring action
#### 1. Dreamverse README and bootstrap script still point at FastVideo-internal
- **Priority:** P0 for a clean public-dependency story.
- **Effort:** Small.
- **Owner:** Dreamverse repo.
- **Evidence:** Dreamverse metadata already points at public FastVideo:
[pyproject](file:///home/william5lin/Dreamverse/pyproject.toml#L17-L22),
[uv source](file:///home/william5lin/Dreamverse/pyproject.toml#L54-L61),
[uv.lock](file:///home/william5lin/Dreamverse/uv.lock#L716-L722).
- **Drift:** README still tells users that `uv` resolves from
`../FastVideo-internal` and that bootstrap expects `../FastVideo-internal`:
[README](file:///home/william5lin/Dreamverse/README.md#L76-L109).
- **Drift:** bootstrap script still defaults to cloning the private repo and
verifying imports from that clone:
[script defaults](file:///home/william5lin/Dreamverse/.agents/skills/bootstrap-fastvideo-private-fork/scripts/bootstrap_fastvideo_private.sh#L7-L11),
[script clone flow](file:///home/william5lin/Dreamverse/.agents/skills/bootstrap-fastvideo-private-fork/scripts/bootstrap_fastvideo_private.sh#L33-L63),
[script import assertion](file:///home/william5lin/Dreamverse/.agents/skills/bootstrap-fastvideo-private-fork/scripts/bootstrap_fastvideo_private.sh#L66-L88).
- **Action:** Replace private-fork bootstrap with public FastVideo bootstrap
or delete the bootstrap once PyPI publication is the default path.
- **Do not overreach:** no FastVideo code change required.
#### 2. Dreamverse carries a 1933-line prompt-enhancer fork
- **Priority:** P1.
- **Effort:** Medium.
- **Owner:** Dreamverse repo, after public prompt enhancer is available.
- **Evidence:** Dreamverse local fork starts at
[server/prompt_enhancer.py](file:///home/william5lin/Dreamverse/server/prompt_enhancer.py#L1-L80).
- **Public replacement:** FastVideo now has provider-agnostic
`PromptEnhancer` with `enhance`, `auto_extend`, `rewrite`, and
`register_provider`:
[public enhancer](file:///home/william5lin/FastVideo/fastvideo/entrypoints/streaming/prompt/enhancer.py#L66-L142).
- **Provider extension point:** custom providers implement `LLMProvider`:
[provider protocol](file:///home/william5lin/FastVideo/fastvideo/entrypoints/streaming/prompt/providers/base.py#L63-L75).
- **Tracking:** DR-1 in open threads already defines the compat-shim shape:
[DR-1](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/open-threads.md#L174-L206).
- **Action:** Replace the fork with a small Dreamverse shim that adapts
public `LLMResponse` to Dreamverse's product response objects and keeps
only product-only extras.
- **Do not overreach:** do not merge Dreamverse's full prompt product layer
into FastVideo unless a second consumer needs the same semantics.
#### 3. `cerebras_ifm` provider is unresolved
- **Priority:** P1 if Dreamverse needs IFM in production; P2 otherwise.
- **Effort:** Small decision plus small/medium implementation.
- **Owner:** Team decision; implementation either Dreamverse-side or public.
- **Public state:** `PromptEnhancerConfig.provider` is currently
`Literal["cerebras", "groq"]`:
[schema](file:///home/william5lin/FastVideo/fastvideo/api/schema.py#L229-L235).
- **Design note:** public Literal excludes `cerebras_ifm` today:
[streaming-server D-3](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/streaming-server.md#L61-L100).
- **Tracking:** DR-2 already frames the public-vs-Dreamverse decision:
[DR-2](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/open-threads.md#L211-L229).
- **Recommended default:** implement IFM as a Dreamverse-side custom provider
registered through `enhancer.register_provider(...)` unless there is a
non-Dreamverse public user.
#### 4. `/healthz`, `/readyz`, and `/status` are not in public `build_app`
- **Priority:** P1 for `BE_FLAVOR=fastvideo` frontend compatibility.
- **Effort:** Medium/Large because route shapes need tests.
- **Owner:** FastVideo public.
- **Public current state:** `build_app` exposes `GET /health` and
`WS /v1/stream`:
[server.py](file:///home/william5lin/FastVideo/fastvideo/entrypoints/streaming/server.py#L126-L160).
- **Dreamverse expected state:** Dreamverse exposes `GET /healthz`,
`GET /readyz`, and `GET /status`:
[routes/health.py](file:///home/william5lin/Dreamverse/server/routes/health.py#L34-L79).
- **Tracking:** open item #1 documents route ownership and files likely to
touch:
[open threads](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/open-threads.md#L69-L99).
- **Design note:** `/curated-presets`, `/prompt-system-config`, and devtools
stay Dreamverse-side, with feature detection:
[streaming route contract](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/streaming-server.md#L232-L259).
#### 5. `fastvideo/models/layerwise_offload.py` exists only internally
- **Priority:** P3 unless memory-tight Dreamverse deployments require it.
- **Effort:** Medium if adopted; low if documented as deferred.
- **Owner:** FastVideo public only if a concrete deployment needs it.
- **Internal evidence:** internal file defines async layerwise CPU offload
manager with pinned CPU memory and prefetch stream:
[layerwise_offload.py](file:///home/william5lin/FastVideo-internal/fastvideo/models/layerwise_offload.py#L1-L20),
[prefetch path](file:///home/william5lin/FastVideo-internal/fastvideo/models/layerwise_offload.py#L127-L180).
- **Public state:** no equivalent public file was identified in this audit.
- **Action:** defer unless Dreamverse or another public deployment hits a
memory ceiling that cannot be handled by existing offload knobs.
- **Decision rule:** if adopted, port as a generic offload utility with
tests; do not make it Dreamverse-specific.
#### 6. Standalone LTX-2 upsampler CLI exists only internally
- **Priority:** P2 for reproducibility; P3 for product runtime.
- **Effort:** Small/Medium after scope decision.
- **Owner:** FastVideo public if standalone upsampling is a supported user
workflow.
- **Internal utility:** `upscale_video_file(...)` reads an existing video,
prepares frame count/resolution, loads VAE + upsampler, and writes an mp4:
[upsample.py](file:///home/william5lin/FastVideo-internal/fastvideo/entrypoints/upsample.py#L120-L180),
[write tail](file:///home/william5lin/FastVideo-internal/fastvideo/entrypoints/upsample.py#L181-L202).
- **Internal CLI:** `fastvideo upsample` wrapper exists internally:
[cli/upsample.py](file:///home/william5lin/FastVideo-internal/fastvideo/entrypoints/cli/upsample.py#L15-L35),
[CLI args](file:///home/william5lin/FastVideo-internal/fastvideo/entrypoints/cli/upsample.py#L48-L130).
- **Public related functionality:** LTX-2 SR refine stage covers the
in-pipeline latent upsample/refine path:
[ltx2_refine.py](file:///home/william5lin/FastVideo/fastvideo/pipelines/basic/ltx2/stages/ltx2_refine.py#L1-L22),
[upsample stage](file:///home/william5lin/FastVideo/fastvideo/pipelines/basic/ltx2/stages/ltx2_refine.py#L116-L180).
- **Action:** decide whether standalone file-to-file upsampling is a public
CLI promise or whether the SR refine stage is sufficient.
#### 7. Reproducible streaming demo config lives only in Dreamverse
- **Priority:** P2.
- **Effort:** Small.
- **Owner:** FastVideo public.
- **Evidence:** canonical demo config currently lives at
[Dreamverse/serve_configs/streaming_demo.yaml](file:///home/william5lin/Dreamverse/serve_configs/streaming_demo.yaml#L1-L12).
- **Config content:** it documents LTX-2 distilled model, one GPU,
no offload, compile settings, NVFP4, refine overrides, default request,
and streaming settings:
[generator block](file:///home/william5lin/Dreamverse/serve_configs/streaming_demo.yaml#L31-L87),
[streaming block](file:///home/william5lin/Dreamverse/serve_configs/streaming_demo.yaml#L108-L149).
- **Memory pointer:** design.md already treats this as the canonical
example:
[design YAML example](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/design.md#L235-L239).
- **Action:** copy/adapt it into
`examples/serving/streaming_demo.yaml` with public-safe comments.
#### 8. LTX-2 stage equivalence is a verification gap, not proven drift
- **Priority:** P2.
- **Effort:** Medium if parity checks are added; small if only manual audit.
- **Owner:** FastVideo public.
- **Public state:** model-specific LTX-2 stages are colocated under
`fastvideo/pipelines/basic/ltx2/stages/`, consistent with the target
layout in [design.md](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/design.md#L175-L205).
- **Example public stage:** `ltx2_refine.py` explicitly says it is a
public-side port of the internal stage and describes the three-stage SR
flow:
[ltx2_refine.py](file:///home/william5lin/FastVideo/fastvideo/pipelines/basic/ltx2/stages/ltx2_refine.py#L1-L22).
- **Action:** verify behavior for the six internal `ltx2_*` stage files
against public colocated stages. If a mismatch is found, file it as a
real drift item with a failing parity test.
### Findings: deferred / accepted residual
These items should not block the public-dependency transition.
1. **StepVideo residual.**
- Dreamverse's model registry is LTX-2/LTX-2.3 only:
[Dreamverse config](file:///home/william5lin/Dreamverse/server/config.py#L28-L45).
- Internal local tests even stub StepVideo modules to keep LTX registry
tests focused:
[test_ltx2_registry.py](file:///home/william5lin/FastVideo-internal/tests/local_tests/test_ltx2_registry.py#L38-L61).
- Conclusion: accepted low-priority deferral unless Dreamverse adds a
StepVideo model.
2. **Internal debug-only `FastVideoArgs` fields.**
- Internal debug fields exist around `FastVideoArgs` and stage/model sums:
[internal grep source](file:///home/william5lin/FastVideo-internal/fastvideo/fastvideo_args.py#L200-L203).
- They are debug-only and not a public user-facing integration surface.
- Conclusion: low-priority; do not add to public schema unless a debug
workflow requires them.
3. **Private request aliases.**
- Public request schema is nested and strict:
[GenerationRequest](file:///home/william5lin/FastVideo/fastvideo/api/schema.py#L193-L204).
- Legacy OpenAI flat fields are compatibility input, not the canonical
public API:
[internal protocol](file:///home/william5lin/FastVideo-internal/fastvideo/entrypoints/openai/protocol.py#L64-L82).
- Conclusion: no action beyond current compat tests.
4. **`experimental["pipeline_config"]` escape hatch.**
- Dreamverse currently uses an explicit in-memory quant config because
typed `transformer_quant: "NVFP4"` does not expose `layer_profile`:
[quantization](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/quantization.md#L86-L97).
- Open thread #4 tracks `layer_profile`:
[open threads](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/open-threads.md#L244-L260).
- Conclusion: defer broader typed carrier design; add `layer_profile`
first if Dreamverse needs base/refine profile selection.
5. **Router sticky routing and active-active semantics.**
- Public router intentionally ships active-passive first and defers
sticky/weighted routing:
[D-15](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/decisions-log.md#L118-L155).
- Follow-ups are tracked:
[D-15 action items](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/decisions-log.md#L175-L201).
- Conclusion: not drift; defer until load-balancing needs are real.
6. **AbsMaxFP8 failure.**
- Pre-existing and not introduced by NVFP4:
[state](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/state.md#L154-L159),
[quantization](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/quantization.md#L202-L214).
- Conclusion: fix separately; not a Dreamverse public-dependency blocker.
### Drift summary table
| # | Item | Priority | Effort | Status | Tracked where | Next action |
|---:|---|---|---|---|---|---|
| 1 | Dreamverse README still names `../FastVideo-internal` | P0 | S | Real drift | [README lines](file:///home/william5lin/Dreamverse/README.md#L76-L109) | Update docs to public FastVideo / PyPI path. |
| 2 | Dreamverse private bootstrap clones internal repo | P0 | S | Real drift | [bootstrap script](file:///home/william5lin/Dreamverse/.agents/skills/bootstrap-fastvideo-private-fork/scripts/bootstrap_fastvideo_private.sh#L7-L11) | Replace or delete private bootstrap. |
| 3 | Dreamverse `prompt_enhancer.py` fork | P1 | M | Real drift | [DR-1](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/open-threads.md#L174-L206) | Build compat shim over public enhancer. |
| 4 | `cerebras_ifm` provider path | P1/P2 | S-M | Real drift / decision | [DR-2](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/open-threads.md#L211-L229) | Choose public provider vs Dreamverse custom provider. |
| 5 | Health route mismatch | P1 | M-L | Real drift | [open item #1](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/open-threads.md#L69-L99) | Add `/healthz`, `/readyz`, `/status` to public build_app. |
| 6 | Missing public streaming demo config | P2 | S | Real drift | [Dreamverse config](file:///home/william5lin/Dreamverse/serve_configs/streaming_demo.yaml#L1-L12) | Add `examples/serving/streaming_demo.yaml`. |
| 7 | Standalone upsampler CLI | P2/P3 | S-M | Real drift if standalone CLI is desired | [internal CLI](file:///home/william5lin/FastVideo-internal/fastvideo/entrypoints/cli/upsample.py#L15-L35) | Decide CLI promise; port or defer. |
| 8 | Layerwise offload utility | P3 | M | Optional internal-only residual (no Dreamverse deployment requires it today) | [internal manager](file:///home/william5lin/FastVideo-internal/fastvideo/models/layerwise_offload.py#L15-L20) | Defer until memory-tight deployment needs it. |
| 9 | LTX-2 stage equivalence | P2 | S-M | Verification gap | [public refine stage](file:///home/william5lin/FastVideo/fastvideo/pipelines/basic/ltx2/stages/ltx2_refine.py#L1-L22) | Add targeted parity audit/test if needed. |
| 10 | StepVideo | P3 | M | Accepted residual | [Dreamverse model registry](file:///home/william5lin/Dreamverse/server/config.py#L28-L45) | No action unless Dreamverse adds StepVideo. |
| 11 | Debug-only fields | P3 | S | Accepted residual | [internal args](file:///home/william5lin/FastVideo-internal/fastvideo/fastvideo_args.py#L200-L203) | Do not publicize unless needed. |
| 12 | `layer_profile` typed quant knob | P2 | M | Tracked gap | [open item #4](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/open-threads.md#L244-L260) | Add typed layer profile if Dreamverse drops escape hatch. |
| 13 | `ltx2_image_crf` per-segment field flow (D-8) | P1 | S | Open verification gap — Dreamverse still passes `ltx2_image_crf=0.0` per [Dreamverse video_generation.py](file:///home/william5lin/Dreamverse/server/video_generation.py#L420-L435); needs trace-through to confirm it lands on `request.stage_overrides.refine.image_crf` rather than being silently dropped | [D-8 in open-threads](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/open-threads.md#L52-L68) | 10-min trace + add a Dreamverse-shape contract test pinning the field. |
| 14 | `video_position_offset_sec` semantics (VPO) | P1 | S | Open decision — persistent-vs-per-segment ambiguity unresolved | [VPO in open-threads](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/open-threads.md#L120-L144) | Confirm semantics with audio team; document + add test. Decision deadline was "before PR 7.6 emits state" — that PR (7.6 / #1257) is now MERGED, so the decision is overdue. |
| 15 | `GpuPool` ABC docstring missing experimental caveat (D-12-A) | P3 | trivial | Tracked gap — `GpuPool` ABC at [gpu_pool.py:74-83](file:///home/william5lin/FastVideo/fastvideo/entrypoints/streaming/gpu_pool.py#L74-L83) lacks the "API may change post-PR-7.10; experimental / server-internal" caveat | [D-12-A](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/open-threads.md#L301-L313) | Edit docstring; trivial. |
| 16 | `GpuPool.run_async()` migration (D-12-B) | P2 | M | Tracked gap — `GpuPool.run() -> Any` should become `run_async() -> AsyncIterator[VideoEvent]` per D-12 / D-12-B | [D-12-B](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/open-threads.md#L317-L327) | Land alongside #1288 merge or in immediate follow-up. |
| 17 | `SessionStore` / `BlobStore` lifecycle policy (SBS) | P2 | M | Tracked gap — in-memory defaults have no eviction/TTL/blob-cleanup policy | [SBS](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/open-threads.md#L278-L294) | Streaming server design pass needed before high-traffic deployment. |
| 13 | Router sticky / active-active | P3 | M | Deferred | [D-15](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/decisions-log.md#L175-L201) | Defer until reconnect/load evidence. |
| 14 | AbsMaxFP8 test failure | P2 | S | Separate tech debt | [state](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/state.md#L154-L159) | Fix outside Dreamverse migration. |
| 15 | Dynamo backend package | P1 | External | Not FastVideo drift | [Dynamo contract](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/cross-repo-surfaces.md#L188-L210) | Reopen Dynamo-side PR after public API lands. |
---
## Part 2 — Integration path tradeoffs
### The four options
#### Option A — Status quo: Dreamverse stays separate and depends on `fastvideo`
**Shape**
- FastVideo remains the Python library and reusable backend runtime.
- Dreamverse remains the product repo with FastAPI product glue and Next.js
frontend.
- Dreamverse `server` extra depends on `fastvideo>=0.1.7`:
[pyproject](file:///home/william5lin/Dreamverse/pyproject.toml#L17-L22).
- Local development can keep using editable `../FastVideo` until PyPI
publication catches up:
[uv.lock](file:///home/william5lin/Dreamverse/uv.lock#L716-L722).
**What it solves**
- Directly satisfies "Dreamverse depends on public FastVideo".
- Keeps frontend release cadence independent.
- Keeps product-specific prompts, routes, and UI in the product repo.
- Minimizes FastVideo packaging and CI growth.
**What it does not solve by itself**
- Does not remove Dreamverse prompt-enhancer fork unless DR-1 is executed.
- Does not give Dreamverse FE compatibility with public `build_app` until
health routes migrate.
- Does not make Dreamverse server itself reusable as a public entrypoint.
**Best fit**
- Default for the next release if the goal is to stop using
FastVideo-internal quickly and safely.
#### Option B — Dreamverse as a subfolder under FastVideo
**Shape**
- One repository: FastVideo contains `dreamverse/server/` and
`dreamverse/apps/web/`.
- Dreamverse can remain a separate package in the same repo, or FastVideo's
build can ignore Dreamverse by default.
- CI must understand Python library tests plus Next.js install/build/test.
**What it solves**
- Eliminates sibling-checkout drift.
- Makes cross-repo integration changes atomic.
- Easier for a single reviewer to see library and product changes together.
**Costs**
- Adds frontend dependency management to a Python ML library repo.
- Couples clone size, CI setup, issue tracking, and review load.
- Forces maintainers to decide whether product assets are included in source
distributions, wheels, docs, and release notes.
**Best fit**
- Only if Dreamverse becomes the primary FastVideo product surface and the
team accepts a product monorepo.
#### Option C — Full merge into `fastvideo.entrypoints.dreamverse.*`
**Shape**
- Dreamverse backend becomes FastVideo code.
- Public import becomes something like
`from fastvideo.entrypoints.dreamverse import build_app`.
- CLI becomes `fastvideo dreamverse-serve --config dreamverse.yaml`.
- Frontend either ships as static assets in the package or as a frontend
extra.
**What it solves**
- One namespace and one release train for library plus product backend.
- No dependency boundary between Dreamverse server and FastVideo internals.
- Product route contract can be tested entirely inside FastVideo CI.
**Costs**
- Maximally expands FastVideo's public/security surface.
- Locks product experiments to FastVideo release cadence.
- Makes private prompt/provider/product assumptions look like framework API.
- Has weak precedent for a Python ML library plus Next.js product being merged
into the library namespace.
**Best fit**
- Only if Dreamverse is no longer a separate product and becomes the
canonical FastVideo UI/serving mode.
#### Option D — Hybrid: backend merges, frontend stays separate
**Shape**
- Reusable backend components merge into public FastVideo.
- Frontend stays in a separate Dreamverse UI repo or Dreamverse product repo.
- The backend should be generic where possible: `fastvideo.entrypoints.streaming`,
not product-only names, unless product-only routes are intentionally
accepted as public API.
- This matches the current trajectory: streaming server, GPU pool, prompt
enhancer, safety/rewrite/session logging, router, NVFP4, and
`generate_async` are public-side work already tracked in the PR roadmap:
[pr-roadmap](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/pr-roadmap.md#L19-L42).
**What it solves**
- Removes FastVideo-internal dependency for reusable backend pieces.
- Keeps product frontend cadence independent.
- Gives non-Dreamverse users a streaming backend and typed API without
carrying the Dreamverse app.
- Gives Dynamo a stable library API while leaving Dynamo package code in
Dynamo:
[Dynamo contract](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/cross-repo-surfaces.md#L188-L210).
**Costs**
- Requires careful boundary discipline: generic streaming/server code in
FastVideo; product routes/prompts/presets in Dreamverse.
- Requires contract tests to prevent drift.
- Some Dreamverse compatibility routes may become public and need support.
**Best fit**
- Best long-term target if the team wants FastVideo to own serving/runtime
infrastructure while keeping Dreamverse as a separately evolving product.
### Comparison matrix
| Criterion | A. Separate dep | B. Subfolder monorepo | C. Full namespace merge | D. Hybrid backend merge |
|---|---|---|---|---|
| Alignment with stated goal | High: Dreamverse depends on public package | Medium: no external dep, but product becomes repo-local | Medium: dependency disappears by absorption | High: reusable backend in public, product separate |
| Time to remove `FastVideo-internal` | Fastest | Medium | Slowest | Medium-fast |
| Build complexity | Low | High: Python + Next.js in one repo | High: Python package plus static/frontend extras | Medium: Python backend only in FastVideo |
| Release cadence | Independent | Coupled clone; releases can still be separate but more friction | Fully coupled | Backend coupled to FastVideo, frontend independent |
| Security surface in FastVideo | Low | Medium/High | Highest | Medium |
| Contributor friction | Low for both repos | Higher for library contributors | Highest; product assumptions in library | Medium; clear backend boundary needed |
| Dependency management | Normal package pin | Workspace/monorepo tooling needed | FastVideo extras/static asset decisions needed | FastVideo extras for backend; FE out-of-tree |
| CI cost | Low/medium | High | High | Medium |
| Contract-test value | High; cross-repo contract tests are essential | Medium; same repo but still useful | Medium; less boundary pressure | High; generic backend vs product boundary |
| Precedent strength | Strong: library/server plus external UI patterns exist | Mixed | Weak for Python ML library + Next.js inside namespace | Strongest match: in-tree server/backend, external UI |
| Packaging risk | Low | Medium/high | High | Medium |
| Future Dynamo fit | Strong | Strong if API remains clean | Risky if product API bleeds in | Strong |
| Frontend iteration speed | Highest | Lower | Lowest | Highest |
| Risk of product-specific API leakage | Low | Medium | High | Medium; controllable with naming discipline |
| Reversibility | High | Medium | Low | Medium/high |
### OSS precedents (with citations)
| Pattern | Project | What it supports | Citation |
|---|---|---|---|
| Library plus in-tree server | vLLM | A Python ML library can ship an in-tree OpenAI-compatible server while clients remain external. | https://github.com/vllm-project/vllm/blob/bcf5cac9fb956788f649d1f5297b74c886a9d6d3/README.md#L64-L74 |
| Service packaging | BentoML | Packaging model + service + dependencies is supported, but CWD packaging creates discipline needs. | https://github.com/bentoml/BentoML/blob/32230a5276a8da8b23c4a06a9ec6272c1993451a/docs/source/build-with-bentoml/asgi.rst#L5-L18 |
| YAML-driven production serving | Ray Serve | Production updates should avoid in-place mutation; use new deployment/traffic switch. | https://docs.ray.io/en/latest/serve/advanced-guides/inplace-updates.html |
| Library/server plus external UI | TGI + ChatUI | Server can live with backend project while UI is separate. | https://github.com/huggingface/text-generation-inference/blob/b4adbf2f6e2e721280bd0ea5f91d70f7d033f5ed/docs/source/basic_tutorials/consuming_tgi.md#L182-L186 |
| Lean library plus examples elsewhere | Transformers.js | Library stays lean; demos/examples can live outside core. | https://github.com/huggingface/transformers.js/blob/f7487c737aa8cafbc106c9adf69dc9578c8f3fe0/README.md#L26-L34 |
| Product monorepo that later split frontend | ComfyUI | Product UI/server monorepo can hit release-cadence mismatch and split FE later. | https://github.com/comfyanonymous/ComfyUI/blob/fed8d5efa6b70d5b24c4c33cb643bfccc39d45b5/README.md#L131-L149 and https://github.com/Comfy-Org/ComfyUI_frontend/blob/60f789d58070a9d1d789b260f83c36d7293a39f0/README.md#L31-L60 |
| Tightly coupled UI/server product | AUTOMATIC1111 SD WebUI | Product repos can couple UI/server tightly, but security surface becomes product-sized. | https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/82a973c04367123ae98bd9abdf80d9eda9b910e2/webui.py#L48-L104 |
#### Precedent synthesis
- Strong precedents exist for a Python ML library shipping a server entrypoint.
- Strong precedents exist for keeping frontend/product UI out of the backend
library repo.
- The cited set does not contain a clean precedent for merging a Next.js
product into a Python ML library namespace.
- The most applicable pattern is **backend/server in the ML project,
product UI outside**.
### Recommendation
#### Recommend Option D, constrained: backend merges as generic FastVideo streaming; frontend stays separate
Recommendation: follow **Option D** as the long-term architecture, but keep
the backend merge generic. In practice, this means continuing the current
public FastVideo path:
- `fastvideo.entrypoints.streaming.*` owns reusable streaming runtime.
- `fastvideo.entrypoints.streaming.gpu_pool` owns generic GPU worker pools.
- `fastvideo.entrypoints.streaming.prompt.*` owns provider-agnostic prompt
operations.
- `fastvideo.entrypoints.streaming.router.*` owns FastVideo-aware routing.
- `fastvideo.api` owns typed construction, requests, results, events, and
continuation state.
- Dreamverse keeps product-only FE, curated presets, prompt UX, product
routes, and launch scripts.
This is effectively the path already underway in PRs #1257, #1258, #1284,
#1286, and #1288:
[PR roadmap](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/pr-roadmap.md#L21-L42).
#### Why not Option A as the final answer?
Option A is the fastest near-term release posture and should be used as the
immediate migration posture. However, plain status quo is not enough for
the ultimate goal because reusable backend pieces still need to live in
public FastVideo so Dreamverse can stop reaching into internal code. That
work is already partly complete:
- GPU pool: [D-12](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/decisions-log.md#L47-L116).
- Prompt enhancer: [PR roadmap 7.7](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/pr-roadmap.md#L32-L35).
- Streaming auxiliaries: [PR roadmap 7.8](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/pr-roadmap.md#L35-L36).
- Router: [D-15](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/decisions-log.md#L118-L155).
- `generate_async`: [streaming-server unlock PR](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/streaming-server.md#L314-L345).
So the practical answer is:
- **Near term:** Option A operationally, after docs/scripts are fixed.
- **Architecture target:** Option D, with generic backend ownership in
FastVideo and product ownership in Dreamverse.
#### Why not Option B?
Option B makes cross-repo coordination easier but imports frontend build,
package, and CI complexity into FastVideo. That is unnecessary while a
normal package dependency plus contract tests can guard the integration.
FastVideo's current repo structure is a Python package with examples and
docs, not a product monorepo:
[codebase map](file:///home/william5lin/FastVideo/.agents/memory/codebase-map/README.md#L5-L75).
#### Why not Option C?
Option C makes the product backend a public FastVideo namespace. That is
only appropriate if the team wants to support Dreamverse as a first-class
FastVideo product surface. Today the known public obligations are generic:
typed requests, streaming server, GPU pool, prompt provider protocol,
router, NVFP4, and Dynamo event APIs. Product-only Dreamverse behavior does
not need to become framework API.
#### Conditions that would change the recommendation
Move from constrained D toward **C** only if all of these become true:
1. Dreamverse is declared the canonical FastVideo serving product.
2. Product routes such as curated presets and prompt-system config are
accepted as public FastVideo API.
3. FastVideo maintainers accept the security and support surface.
4. Release cadence for product UX and FastVideo core is intentionally
coupled.
5. Frontend packaging/static asset strategy is explicitly owned by
FastVideo.
Move from constrained D back toward **A** if any of these become true:
1. Prompt enhancement, router, or GPU pool turn out to be Dreamverse-only.
2. No second user appears for the streaming backend outside Dreamverse.
3. FastVideo maintainers want to minimize serving surface and publish only
Python library APIs.
4. Dreamverse needs product changes faster than FastVideo can release.
5. Security review rejects in-tree serving/router responsibilities.
### Migration sketch for the recommended path
#### Phase 0 — Land the public backend stack
- **Effort:** Large, already in flight.
- **Owner:** FastVideo public.
- **Files:** #1288 scope, especially `fastvideo/api/`,
`fastvideo/entrypoints/video_generator.py`,
`fastvideo/entrypoints/streaming/`, LTX-2 pipeline stages, NVFP4 files,
and contract tests.
- **Exit criteria:** #1288 merges; public `fastvideo.api.VideoEvent` and
`VideoGenerator.generate_async` are available:
[results.py](file:///home/william5lin/FastVideo/fastvideo/api/results.py#L109-L164),
[video_generator.py](file:///home/william5lin/FastVideo/fastvideo/entrypoints/video_generator.py#L264-L332).
#### Phase 1 — Fix Dreamverse dependency docs and bootstrap
- **Effort:** Small.
- **Owner:** Dreamverse.
- **Files:**
- [README.md](file:///home/william5lin/Dreamverse/README.md#L76-L109)
- [bootstrap script](file:///home/william5lin/Dreamverse/.agents/skills/bootstrap-fastvideo-private-fork/scripts/bootstrap_fastvideo_private.sh#L7-L11)
- [pyproject.toml](file:///home/william5lin/Dreamverse/pyproject.toml#L17-L22)
- [uv.lock](file:///home/william5lin/Dreamverse/uv.lock#L716-L722)
- **Exit criteria:** no user-facing docs or scripts mention
`FastVideo-internal` as the expected dependency path.
#### Phase 2 — Add public health/readiness/status route compatibility
- **Effort:** Medium/Large.
- **Owner:** FastVideo public.
- **Files likely to touch:**
- `fastvideo/entrypoints/streaming/server.py::build_app`
- new `fastvideo/entrypoints/streaming/health.py`
- tests under `fastvideo/tests/entrypoints/streaming/`
- **Source route shapes:**
[Dreamverse health routes](file:///home/william5lin/Dreamverse/server/routes/health.py#L34-L79).
- **Tracking:** [open item #1](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/open-threads.md#L69-L99).
- **Exit criteria:** Dreamverse FE can target public `build_app` for
`/healthz`, `/readyz`, `/status`, and `/v1/stream`; product-only routes
remain feature-detected.
#### Phase 3 — Replace Dreamverse prompt enhancer fork
- **Effort:** Medium.
- **Owner:** Dreamverse.
- **Files likely to touch:**
- new `Dreamverse/server/prompting/_internal_compat.py`
- `Dreamverse/server/runtime.py`
- `Dreamverse/server/main.py`
- `Dreamverse/server/prompt_enhancer.py`
- **Public API:**
[PromptEnhancer](file:///home/william5lin/FastVideo/fastvideo/entrypoints/streaming/prompt/enhancer.py#L66-L142),
[LLMProvider](file:///home/william5lin/FastVideo/fastvideo/entrypoints/streaming/prompt/providers/base.py#L63-L75).
- **Tracking:** [DR-1](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/open-threads.md#L174-L206).
- **Exit criteria:** Dreamverse no longer carries a full local fork for the
generic prompt operations public FastVideo already owns.
#### Phase 4 — Decide and implement `cerebras_ifm`
- **Effort:** Small decision plus small/medium implementation.
- **Owner:** Team decision, then Dreamverse or FastVideo.
- **Default recommendation:** Dreamverse-side custom provider.
- **Public schema source:**
[PromptEnhancerConfig](file:///home/william5lin/FastVideo/fastvideo/api/schema.py#L229-L235).
- **Tracking:** [DR-2](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/open-threads.md#L211-L229).
- **Exit criteria:** Dreamverse IFM provider works after prompt fork removal.
#### Phase 5 — Move streaming demo config into FastVideo examples
- **Effort:** Small.
- **Owner:** FastVideo public.
- **Source:**
[Dreamverse streaming_demo.yaml](file:///home/william5lin/Dreamverse/serve_configs/streaming_demo.yaml#L1-L149).
- **Target:** `examples/serving/streaming_demo.yaml`.
- **Exit criteria:** users can reproduce the typed streaming path from the
FastVideo repo without checking out Dreamverse.
#### Phase 6 — Remove `experimental["pipeline_config"]` where practical
- **Effort:** Medium for `layer_profile`; Large for a full typed
`dit_config.quant_config` carrier.
- **Owner:** FastVideo public, then Dreamverse cleanup.
- **Tracking:**
[open item #4](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/open-threads.md#L244-L260),
[quantization follow-up](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/quantization.md#L175-L200).
- **Exit criteria:** Dreamverse can express its quant layer profile through
typed config instead of in-memory mutation.
#### Phase 7 — Decide standalone upsampler CLI
- **Effort:** Small/Medium.
- **Owner:** FastVideo public.
- **Input:** internal standalone utility
[upsample.py](file:///home/william5lin/FastVideo-internal/fastvideo/entrypoints/upsample.py#L120-L180)
and internal CLI
[cli/upsample.py](file:///home/william5lin/FastVideo-internal/fastvideo/entrypoints/cli/upsample.py#L48-L130).
- **Public alternative:** SR refine stage already covers in-pipeline latent
upsampling:
[ltx2_refine.py](file:///home/william5lin/FastVideo/fastvideo/pipelines/basic/ltx2/stages/ltx2_refine.py#L116-L180).
- **Exit criteria:** explicit decision: port CLI, document refine-stage-only
support, or defer.
#### Phase 8 — Validate LTX-2 stage parity and offload residuals
- **Effort:** Small/Medium for stage parity; Medium for layerwise offload.
- **Owner:** FastVideo public.
- **Stage source:**
[public LTX-2 stages](file:///home/william5lin/FastVideo/fastvideo/pipelines/basic/ltx2/stages/).
- **Offload source:**
[internal layerwise offload](file:///home/william5lin/FastVideo-internal/fastvideo/models/layerwise_offload.py#L15-L20).
- **Exit criteria:** no known behavior gap between internal and public LTX-2
stages; offload is either deliberately deferred or ported with tests.
### Open questions
1. **Which provider path for `cerebras_ifm`?**
- Public provider or Dreamverse-side custom provider?
- Default recommendation: Dreamverse-side unless there is another user.
- Source: [DR-2](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/open-threads.md#L211-L229).
2. **Should public FastVideo support standalone LTX-2 file upsampling?**
- If yes, port internal CLI.
- If no, document that SR support is pipeline-refine only.
- Sources: [internal CLI](file:///home/william5lin/FastVideo-internal/fastvideo/entrypoints/cli/upsample.py#L15-L35),
[public refine stage](file:///home/william5lin/FastVideo/fastvideo/pipelines/basic/ltx2/stages/ltx2_refine.py#L1-L22).
3. **Does Dreamverse need layerwise CPU offload?**
- If memory-tight deployments require it, port as generic FastVideo.
- Otherwise defer.
- Source: [internal offload manager](file:///home/william5lin/FastVideo-internal/fastvideo/models/layerwise_offload.py#L15-L20).
4. **How much Dreamverse route surface should FastVideo own?**
- Health/readiness/status should migrate because they are part of
streaming-server compatibility.
- Curated presets and prompt-system config should stay Dreamverse-side
unless product policy changes.
- Source: [route contract](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/streaming-server.md#L232-L259).
5. **Should `layer_profile` be the only near-term quant typed addition?**
- Adding `layer_profile` is bounded.
- A typed carrier for arbitrary mutated `PipelineConfig` is larger design
work.
- Source: [quantization follow-ups](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/quantization.md#L175-L200).
6. **When does Option D become Option C?**
- Only if Dreamverse backend routes become public FastVideo product API.
- Until then, keep generic streaming code in FastVideo and product code in
Dreamverse.
---
## Part 3 — Action items
1. **P0 / S — Update Dreamverse README dependency notes.**
- Replace `../FastVideo-internal` with public FastVideo instructions.
- Preserve local editable `../FastVideo` dev flow where useful.
- Source: [README stale lines](file:///home/william5lin/Dreamverse/README.md#L76-L109).
2. **P0 / S — Replace or remove private FastVideo bootstrap script.**
- Current script clones `FastVideo-internal` and verifies imports from it.
- Source: [script](file:///home/william5lin/Dreamverse/.agents/skills/bootstrap-fastvideo-private-fork/scripts/bootstrap_fastvideo_private.sh#L7-L11).
3. **P1 / M-L — Add `/healthz`, `/readyz`, and `/status` to public `build_app`.**
- Keep `/curated-presets` and prompt-system config in Dreamverse.
- Source: [open item #1](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/open-threads.md#L69-L99).
4. **P1 / M — Replace Dreamverse prompt-enhancer fork with compat shim.**
- Wrap public `PromptEnhancer`.
- Keep only Dreamverse-specific metadata and product fallback behavior.
- Source: [DR-1](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/open-threads.md#L174-L206).
5. **P1 / S-M — Decide `cerebras_ifm` provider path.**
- Default: Dreamverse custom provider via `register_provider`.
- Source: [DR-2](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/open-threads.md#L211-L229).
6. **P2 / S — Add `examples/serving/streaming_demo.yaml` to FastVideo.**
- Start from Dreamverse config and remove Dreamverse-private comments.
- Source: [streaming_demo.yaml](file:///home/william5lin/Dreamverse/serve_configs/streaming_demo.yaml#L1-L149).
7. **P2 / M — Verify each public LTX-2 colocated stage against internal behavior.**
- Start with refine, denoising, latent prep, image conditioning, text
encoding, and audio decoding.
- Source: [public refine stage](file:///home/william5lin/FastVideo/fastvideo/pipelines/basic/ltx2/stages/ltx2_refine.py#L1-L22).
8. **P2 / M — Add typed `transformer_quant_layer_profile` if Dreamverse needs it.**
- Thread schema → compat → `FastVideoArgs._apply_transformer_quant`.
- Source: [open item #4](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/open-threads.md#L244-L260).
9. **P2 / S-M — Decide standalone LTX-2 upsampler CLI support.**
- Port internal CLI only if file-to-file upsampling is a public workflow.
- Source: [internal upsample CLI](file:///home/william5lin/FastVideo-internal/fastvideo/entrypoints/cli/upsample.py#L15-L35).
10. **P2 / S — Fix pre-existing AbsMaxFP8 test failure separately.**
- Do not block Dreamverse migration on it.
- Source: [open item #2](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/open-threads.md#L100-L117).
11. **P2 / S-M — Document public streaming install extras and dependencies.**
- Include router `websockets`, prompt enhancer provider SDKs, and optional
safety classifier extras.
- Source: [D-16 dependency note](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/decisions-log.md#L224-L242).
12. **P2 / S — Keep contract tests in the FastVideo CI path.**
- Guard Dreamverse shape, Dynamo shape, and async events.
- Sources: [Dreamverse test](file:///home/william5lin/FastVideo/fastvideo/tests/contract/test_dreamverse_shape.py#L1-L26),
[Dynamo test](file:///home/william5lin/FastVideo/fastvideo/tests/contract/test_dynamo_shape.py#L1-L19),
[async test](file:///home/william5lin/FastVideo/fastvideo/tests/contract/test_generate_async.py#L1-L7).
13. **P3 / M — Defer layerwise offload until a deployment needs it.**
- Port only as generic FastVideo utility with tests.
- Source: [internal offload](file:///home/william5lin/FastVideo-internal/fastvideo/models/layerwise_offload.py#L15-L20).
14. **P3 / M — Defer StepVideo public parity for this integration.**
- Dreamverse model registry is LTX-2/LTX-2.3 only.
- Source: [Dreamverse config](file:///home/william5lin/Dreamverse/server/config.py#L28-L45).
15. **P3 / S — Do not add debug-only fields to public schema by default.**
- Keep them private unless there is a user-facing debugging workflow.
- Source: [internal debug args](file:///home/william5lin/FastVideo-internal/fastvideo/fastvideo_args.py#L200-L203).
16. **P3 / M — Keep router active-active and sticky routing deferred.**
- Add only when session-routing evidence justifies it.
- Source: [D-15 action items](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/decisions-log.md#L175-L201).
17. **P3 / S — Preserve Dynamo as an external backend package.**
- FastVideo should expose typed API; Dynamo code lives in Dynamo.
- Source: [Dynamo contract](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/cross-repo-surfaces.md#L188-L210).
18. **P3 / S — After #1288 merges, update memory-dir state.**
- Mark item D resolved and update branch tips.
- Source: [runbook post-merge steps](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/runbook.md#L51-L70).
19. **P3 / S — Remove stale split-PR mental model from follow-up docs.**
- #1288 is the current vehicle; split bookmarks are historical.
- Source: [D-17 implications](file:///home/william5lin/FastVideo/.agents/memory/dreamverse-integration/decisions-log.md#L34-L45).
20. **P3 / S — Keep product-only Dreamverse frontend out of FastVideo unless explicitly re-scoped.**
- This preserves release cadence and avoids packaging bloat.
- Source: [Dreamverse baseline](file:///home/william5lin/Dreamverse/README.md#L5-L16).
@@ -1,498 +0,0 @@
# Open Threads — Active Follow-Ups
Live work items with priority, effort estimate, dependencies, and
recommended next action.
For why each item is open see [decisions-log.md](decisions-log.md). For
PR-level context see [pr-roadmap.md](pr-roadmap.md).
**Last updated:** 2026-05-05 (strategy reversal — PR #1287 CLOSED, replaced
by mega-PR #1288 on `will/ltx2_sr_port` @ `b36bdbc9` covering the full
6-layer stack at once. See [decisions-log.md D-17](decisions-log.md#d-17).
Item D resolution gate is now #1288 merge instead of #1287; same content,
different vehicle.).
## Priority overview
| # | Pri | Item | Effort | Unblocks |
|---|---|---|---|---|
| **D-8** | High | Verify `ltx2_image_crf` post-`d80c2a8` | 10 min | Confirms typed stage-override path actually flows; closes a latent silent-drop bug |
| **1** | High | Migrate `/healthz`+`/readyz`+`/status` into FastVideo `build_app` | M-L | Closes BE_FLAVOR=fastvideo FE-compatibility; closes streaming-upstream contract debt |
| **2** | High | Fix pre-existing AbsMaxFP8 test failure | S | Self-contained quantization tech debt |
| **VPO** | High | Decide `video_position_offset_sec` semantics (a vs b) | 30 min | Unblocks PR 7.6 state emission |
| **D** | 🟢 in flight | Implement `generate_async` — content shipped in mega-PR **#1288** on `will/ltx2_sr_port` @ `b36bdbc9` (was #1287, CLOSED + re-routed per [D-17](decisions-log.md#d-17)) | L | Closes Q-5/Q-9/PR-7.5 TODOs simultaneously; enables Dynamo backend; unblocks audio re-encode; enables `GpuPool.run_async()` migration (D-12-B). Resolution gate: #1288 merge. |
| **DR-1** | High | Dreamverse: create `prompting/_internal_compat.py` shim + replace local `prompt_enhancer.py` (1933 LOC) — **PR #1258 has merged (`f673423b`); now actionable** | M (~150-200 LOC shim, replace upstream wiring) | Lets Dreamverse stop carrying a 1933-LOC fork |
| **DR-2** | Med | Decide `cerebras_ifm` provider path: (a) public Literal + `CerebrasIFMProvider` shipped, OR (b) Dreamverse-side custom provider via `enhancer.register_provider(...)` | S (decision) + S-M (impl) | Resolves the cerebras_ifm gap left by PR #1258. Same item as legacy #3 below; DR-2 is the Dreamverse-side framing. |
| **3** | Med | Add `cerebras_ifm` to `PromptEnhancerConfig.provider` Literal + provider | S-M | Public-side resolution if DR-2 picks (a) |
| **4** | Med | Expose `layer_profile` on typed `engine.quantization` | M | Removes Dreamverse's `experimental["pipeline_config"]` dodge for stage profiles |
| **5** | Med | Design typed `dit_config.quant_config` carrier | L design + L impl | Removes broader `experimental["pipeline_config"]` escape hatch |
| **SBS** | Med | `SessionStore` / `BlobStore` lifecycle policy | M design | Needed in PR 7.5 design pass |
| **D-12-A** | Med | Update `GpuPool` ABC docstring: mark "API may change post-PR-7.10; experimental / server-internal" | trivial | Prevents accidental promotion of streaming-internal API to framework-level |
| **D-12-B** | Med | Replace `GpuPool.run() -> Any` with `run_async() -> AsyncIterator[VideoEvent]` in PR 7.10 cycle | M | Closes the streaming-server cancellation TODO; converges with `generate_async` |
| **D-13-A** | Med | Document `fastvideo.entrypoints.streaming.prompt.*` in user-facing docs as "streaming-server scoped"; avoid framework-level framing | trivial (docs only) | Keeps future move to `fastvideo.prompt.*` cheap |
| **D-13-B** | Low | Add optional `client_factory` parameter to `LLMProvider` for `httpx.AsyncClient` pooling | S | Only if metrics show connect/TLS overhead is meaningful |
| **D-12-C** | Low | Avoid locking `PoolAssignment.gpu_id: int` as public; rename to `worker_id` (already exists) or add `device_ids: list[int]` for topology-aware pooling | S | Future multi-GPU-per-worker refactor stays cheap |
| **6** | Low | Audio attention quantization profile + test update | S | Future audio quant exploration |
| **7** | Low | Schema parity inventory cleanup (env-driven prompt fields) | S-M | Long-term consistency |
| **8** | Low | Stale `apps/web/test-results/` dir cleanup | trivial | Cosmetic |
| **11** | Low | Promote LTX-2 prompt orchestration (locked segments, segment_prompts JSON shape, rollout id/label) to `fastvideo.entrypoints.streaming.prompt.ltx2_orchestration` | M | Resolves Q-2 from decisions-log when a second LTX-2-style consumer appears |
| **12** | Low | When streaming server starts using `PromptSafetyFilter`, ensure operator-visible logging on `SafetyDecision.UNAVAILABLE` results | trivial | Surfaces degraded-safety state to operators (per D-14 Watch-Out item) |
| **13** | Low | When sticky session routing is needed, add `ReplicaRegistry.select(routing_key: str | None = None)` and document where `session_id` lives (WS URL/header preferred over first JSON frame) | M | Forward-compat from D-15 — keeps the door open without buffering/peeking |
| **14** | Low | At higher load, add `_bridge_session()` max-size + timeout limits OR recommend Envoy/HAProxy in front | S-M | The libraries' basic backpressure suffices for MVP; document the limit per D-15 |
| **15** | Low | If active-active multi-primary becomes a requirement, define behavior (round-robin within healthy primaries, weighted, sticky-by-key) | M | Currently `RouterConfig.__post_init__` rejects multi-primary; D-15 deferred until evidence |
| **~~Source-doc disposition~~** | ~~Med~~ | ~~Disposition of 7 untracked source docs~~ | ~~trivial~~ | ✅ **Resolved 2026-05-03** — moved into [source-archive/](source-archive/) |
| **~~9~~** | ~~Low~~ | ~~Commit-message cleanup: PR 8's 3 commits still have `[8/n] Improve API:` prefix~~ | ~~S~~ | ✅ **Resolved 2026-05-04** — bundled into the will/api_7.8 prep rebase. PR 8's 3 commits now read `[type] streaming: ...` |
| **~~10~~** | ~~Low~~ | ~~Commit-message cleanup: PR 7.8/7.9 commits have `streaming: streaming X` duplication~~ | ~~S~~ | ✅ **Resolved 2026-05-04** — bundled into the will/api_7.8 prep rebase. 3 commits dedup'd. |
---
## High priority
### D-8: Verify `ltx2_image_crf` typed flow post-`d80c2a8`
**Why:** Apr 26 dreamverse_review documented this field getting silently
dropped by the public `SamplingParam`. May 2 `d80c2a8` (Dreamverse)
refactored to typed `GeneratorConfig` + `preset_overrides`. Whether
`image_crf` now flows through `request.stage_overrides.refine.image_crf`
(per [design.md](design.md) mapping) or is still dropped is unverified.
**Action:**
1. Read [`Dreamverse/server/video_generation.py`](file:///home/william5lin/Dreamverse/server/video_generation.py)
post-`d80c2a8` for `image_crf` handling
2. Trace through to FastVideo's `request.stage_overrides.refine.image_crf`
3. Confirm runtime consumption in [`fastvideo/pipelines/basic/ltx2/`](file:///home/william5lin/FastVideo/fastvideo/pipelines/basic/ltx2/)
**Effort:** 10 min, no code changes.
**Outcome:** Either confirms working OR identifies bug → opens fix item.
### Item #1: Migrate `/healthz`+`/readyz`+`/status` into `build_app`
**Why:** Today
[`fastvideo.entrypoints.streaming.server.build_app`](file:///home/william5lin/FastVideo/fastvideo/entrypoints/streaming/server.py)
exposes only `/health` + `/v1/stream`. Dreamverse FE expects all of
`/healthz`, `/readyz`, `/status`, `/curated-presets`,
`/prompt-system-config`, devtools.
The streaming-server-upstream plan (line 84) explicitly lists
`/healthz`+`/readyz`+`/status` as part of the contract that the upstream
of `realtime/` → `streaming/` must preserve. They were deferred from
PR 7.5's MVP. `/curated-presets` and `/prompt-system-config` are
operator-side and stay in Dreamverse (FE feature-detects).
**Action:**
1. Read PR 7.5 (#1251) `build_app` to scope what's there
2. Read [`Dreamverse/server/routes/health.py`](file:///home/william5lin/Dreamverse/server/routes/health.py)
for the route shapes Dreamverse already consumes
3. Propose route migration as commit on top of `will/api_7.5` or as
part of PR 7.10 cycle
4. Land
**Effort:** Medium-Large (route shapes need preservation; tests).
**Dependencies:** None blocking; can land anytime.
**Files likely to touch:**
- `fastvideo/entrypoints/streaming/server.py::build_app`
- New `fastvideo/entrypoints/streaming/health.py`
- Tests in `fastvideo/tests/entrypoints/streaming/`
### Item #2: AbsMaxFP8 pre-existing test failure
**Why:** [`fastvideo/tests/ops/quantization/test_absmax_fp8.py::test_create_weights_rejects_invalid_dtype`](file:///home/william5lin/FastVideo/fastvideo/tests/ops/quantization/test_absmax_fp8.py)
fails with `AssertionError not raised`. Pre-existing on `main`; verified
NOT introduced by NVFP4 work via `git stash`.
**Action:**
1. `git log --oneline fastvideo/tests/ops/quantization/test_absmax_fp8.py`
to find when it last passed
2. Either:
- Restore the assert in `AbsMaxFP8LinearMethod.create_weights` if
intentional behavior was lost
- Drop the test if assert is no longer correct
3. Verify
**Effort:** Small.
**Dependencies:** None.
### Item VPO: `video_position_offset_sec` semantics
**Why:** Per
[`fastvideo/pipelines/basic/ltx2/continuation.py`](file:///home/william5lin/FastVideo/fastvideo/pipelines/basic/ltx2/continuation.py),
`LTX2ContinuationState.video_position_offset_sec` exists as a state
field. Two valid interpretations:
- **(a) Persistent across segments** — accumulating time offset for long
sessions; useful for time-coherent audio chaining.
- **(b) Per-segment hint that rides on the carrier** — runtime
overwrites every time; field is harmless redundancy.
Dreamverse computes `prefix_sec = float(audio_extra) / 24.0` per segment
in `apply_audio` and currently does NOT persist it on
`ContinuationState`. Field's docstring leans toward (b).
**Decision deadline:** before PR 7.6 starts emitting/consuming the
field (PR 7.6 branch is ready, not yet PR'd).
**Action:**
1. Confirm field's intended semantics with audio team
2. If (a): document the accumulation rule explicitly + add tests
3. If (b): leave docstring as-is + add test confirming overwrite
**Effort:** 30 min discussion + small implementation.
### Item D: Implement `generate_async` (PR 7.10)
**Why:** Highest leverage. Closes:
- D-5 / Q-5: audio re-encode for cross-segment continuity
- Q-9: Dynamo progress passthrough (deferred)
- PR 7.5's mid-segment cancellation TODO
- Unblocks Dynamo native backend integration
- **D-12-B**: enables `GpuPool.run() -> run_async() -> AsyncIterator[VideoEvent]` migration
**Action:** See [streaming-server.md](streaming-server.md) "PR 7.10 — the
unlock PR" section for scoping.
**Effort:** Large.
**Dependencies:** Best after PR 7.6 lands (gpu_pool upstream).
**Files:**
- `fastvideo/entrypoints/video_generator.py` — add `generate_async`,
refactor `generate_video` as wrapper
- `fastvideo/api/results.py` — add `VideoEvent`/`VideoProgressEvent`/
`VideoPartialEvent`/`VideoFinalEvent`
- `fastvideo/entrypoints/streaming/server.py` — consume `generate_async`,
remove TODO markers
- `fastvideo/entrypoints/streaming/gpu_pool.py` — add `run_async()`
forwarding events from worker to caller
- New `fastvideo/tests/entrypoints/test_generate_async.py`
- New `fastvideo/tests/contract/test_dynamo_shape.py` (already in PR 8)
### Item DR-1: Dreamverse — replace local `prompt_enhancer.py` with public + compat shim
**Why:** Today Dreamverse carries `Dreamverse/server/prompt_enhancer.py`
(1933 LOC) — a local copy/derivative of the FastVideo-internal version.
After PR #1258 merges, Dreamverse should switch to the public
`fastvideo.entrypoints.streaming.prompt.PromptEnhancer` and delete most
of the local module.
**Migration shape:**
1. **Create** `Dreamverse/server/prompting/_internal_compat.py` (~150-200 LOC):
- Wraps public `PromptEnhancer.enhance()` → returns `EnhanceResult` shape Dreamverse expects
- Wraps public `PromptEnhancer.auto_extend()` — JSON-parses `LLMResponse.content` into `{"next_prompt": "..."}`
- Wraps public `PromptEnhancer.rewrite()` — JSON-parses into `{"segment_prompts": [...]}` with lenient fallback for malformed JSON
- Layers locked-segment + rollout_id + rollout_label metadata back on top
2. **Update** `Dreamverse/server/runtime.py + main.py` — replace `from prompt_enhancer import PromptEnhancer` with `from prompting._internal_compat import PromptEnhancer`
3. **Delete most of** `Dreamverse/server/prompt_enhancer.py` (1933 LOC). Keep only the bits that don't have a public equivalent:
- Race-based parallel fallback (`_run_provider_race`) — Dreamverse-specific tail-latency optimization
- `cerebras_ifm` provider — pending DR-2 decision
- Multi-classifier prompt safety (NSFW + hate-speech chained) — public ships single classifier
4. **Tests** — verify Dreamverse session controllers still see the expected response shapes through the shim
**Effort:** Medium (~150-200 LOC shim + replace upstream wiring + delete 1700+ LOC local module + test fixture updates).
**Dependencies:**
- PR #1258 must merge first (publishes `fastvideo.entrypoints.streaming.prompt.*`)
- DR-2 informs the cerebras_ifm path
**Files:**
- New: `Dreamverse/server/prompting/_internal_compat.py`
- Modified: `Dreamverse/server/runtime.py`, `Dreamverse/server/main.py`
- Mostly deleted: `Dreamverse/server/prompt_enhancer.py`
---
## Medium priority
### Item DR-2: Decide `cerebras_ifm` provider path
**Why:** Public PR #1258's `PromptEnhancerConfig.provider` is
`Literal["cerebras", "groq"]`. Internal supports `"cerebras_ifm"` (the
Cerebras IFM API endpoint with different auth). Dreamverse needs
`cerebras_ifm` working post-migration.
Two options:
| Option | Approach | Pros | Cons |
|---|---|---|---|
| **(a) Public** | Add `"cerebras_ifm"` to public Literal + ship `CerebrasIFMProvider` in `fastvideo/entrypoints/streaming/prompt/providers/cerebras_ifm.py` | Discoverable; users with IFM access can use typed config | Adds ~50 LOC + Literal extension to public surface |
| **(b) Dreamverse-side** | Implement `CerebrasIFMProvider` Dreamverse-side as a custom `LLMProvider`, register via `enhancer.register_provider(CerebrasIFMProvider())` | Zero public surface change; private endpoint stays private | Slightly more boilerplate Dreamverse-side; not surfaced to non-Dreamverse users |
**Recommendation:** Option (b) is more contained. Option (a) is more
discoverable. Default to (b) unless there's a third-party user who needs
IFM access. The Dreamverse-side PR carrying DR-1 is the natural place to
make this decision.
**Effort:** Small (decision) + Small-Medium (implementation).
**Dependencies:** DR-1 (compat shim creation).
### Item #3: `cerebras_ifm` provider in public Literal
**Why:** Same item as DR-2 from the public-side framing. If DR-2 picks
option (a), this is the implementation. If DR-2 picks option (b), this
item is closed without implementation.
**Action:** See DR-2.
**Effort:** S-M.
### Item #4: Expose `layer_profile` on typed `engine.quantization`
**Why:** Today `transformer_quant: "NVFP4"` always constructs
`NVFP4Config()` with default `layer_profile="refine"`. Dreamverse
dodges via `experimental["pipeline_config"]`.
**Action:**
1. Add `transformer_quant_layer_profile: str | None = None` to
`QuantizationConfig` in [`schema.py`](file:///home/william5lin/FastVideo/fastvideo/api/schema.py)
2. Thread through [`compat.py`](file:///home/william5lin/FastVideo/fastvideo/api/compat.py)
3. Update `_apply_transformer_quant` in
[`fastvideo_args.py`](file:///home/william5lin/FastVideo/fastvideo/fastvideo_args.py)
to pass profile
4. Update Dreamverse to drop the `experimental["pipeline_config"]`
dodge in favor of typed knob
5. Tests in [`test_typed_quant_flow.py`](file:///home/william5lin/FastVideo/fastvideo/tests/api/test_typed_quant_flow.py)
**Effort:** Medium.
**Files:** schema.py, compat.py, fastvideo_args.py, test_typed_quant_flow.py,
+ Dreamverse/server/video_generation.py.
### Item #5: Typed `dit_config.quant_config` carrier
**Why:** The `experimental["pipeline_config"]` escape hatch in
Dreamverse should eventually become a typed field. Design TBD.
**Action:** Heaviest design work. Should consult Oracle.
**Effort:** Large design + Large implementation.
**Dependencies:** #4 should land first; this is the "final form" of #4.
### Item SBS: `SessionStore` / `BlobStore` lifecycle policy
**Why:** PR 7's in-memory implementations have no eviction, no TTL, no
automatic blob cleanup on state replacement. Documented as per-deployment
policy decision.
When PR 7.5/7.6 land the live consumer, who owns:
- bounded session capacity (LRU? TTL? hard max?)
- blob `drop()` chained when state is replaced
- session expiry on websocket disconnect
**Recommendation:** streaming server's session manager. Worth stating
explicitly in PR 7.5's design.
**Effort:** Medium design + small implementation.
### Item D-12-A: Update `GpuPool` ABC docstring — mark experimental
**Why:** Per D-12 in [decisions-log.md](decisions-log.md), `GpuPool`
should be documented as "API may change post-PR-7.10; experimental /
server-internal" to prevent accidental promotion of streaming-internal
API to framework-level. PR #1257 merged without this caveat.
**Action:** Edit
[`fastvideo/entrypoints/streaming/gpu_pool.py`](file:///home/william5lin/FastVideo/fastvideo/entrypoints/streaming/gpu_pool.py)
class docstring on `GpuPool` ABC. Add a note: "API may change post-PR-7.10
when run_async() lands; treat as server-internal for now."
**Effort:** Trivial.
**Dependencies:** None.
### Item D-12-B: Replace `GpuPool.run() -> Any` with `run_async() -> AsyncIterator[VideoEvent]`
**Why:** Per D-12, this is the canonical evolution post-PR-7.10. Closes
the streaming server's cancellation TODO and converges the streaming +
OpenAI + Dynamo consumers on a single async API.
**Action:** As part of PR 7.10 cycle:
1. Add `GpuPool.run_async(session_id, request) -> AsyncIterator[VideoEvent]`
2. Worker forwards events through `result_queue` with type discriminator
3. Streaming server replaces `await pool.run(...)` with `async for event in pool.run_async(...)`
4. Sync `run()` becomes a thin compat wrapper that collects events and returns the final
5. Cancellation propagates: client disconnect → `asyncio.CancelledError` → worker stops mid-step
**Effort:** Medium. Adds ~50-100 LOC + tests.
**Dependencies:** Item D (PR 7.10 — `generate_async` on `VideoGenerator`).
### Item D-13-A: Document `streaming/prompt/*` as streaming-scoped
**Why:** Per D-13 in [decisions-log.md](decisions-log.md), the prompt
enhancer is currently scoped to streaming-server use even though the
abstraction is general. Phrase user-facing docs as "streaming-server
prompt enhancement" to keep future move to `fastvideo.prompt.*` cheap.
**Action:** When PR 12 (docs migration) is written, the prompt enhancer
section should:
- Be titled "Streaming Server Prompt Enhancement", not "Prompt API"
- Note the 3 fixed operations (`enhance` / `auto_extend` / `rewrite`) are
shaped by LTX-2 streaming session needs
- Note that consumers wanting custom prompt operations can use
`provider.complete()` directly with their own LLMRequest
- Avoid `from fastvideo import LLMProvider` exports until a second
consumer exists
**Effort:** Trivial (docs only).
**Dependencies:** PR 12 (docs migration).
---
## Low priority
### Item D-13-B: Optional `client_factory` parameter for `httpx.AsyncClient` pooling
**Why:** Today `_openai_compat.py` instantiates `httpx.AsyncClient` per
call (no connection pooling). Reviewer flagged inefficient. Team chose
simplicity for the expected scale (~6-10 enhancer calls per LTX-2
session). If real-world metrics show connect/TLS overhead is meaningful,
add an optional `client_factory: Callable[[], httpx.AsyncClient] | None`
parameter to providers so they can share a pool.
**Action:** Only when metrics justify. Add `client_factory=None` parameter
to `CerebrasProvider` / `GroqProvider` constructors and pass through to
`complete_openai_compatible()`. Default to current per-call behavior.
**Effort:** Small.
**Dependencies:** None blocking; only act on real perf data.
### Item D-12-C: Avoid locking `PoolAssignment.gpu_id: int` as public
**Why:** Today `PoolAssignment` exposes `gpu_id: int`, assuming
one-GPU-per-worker. Future topology-aware pooling may need
`device_ids: list[int]` (one worker = group of GPUs running internal
`MultiprocExecutor`). Don't freeze the int field as public API.
**Action:**
- Treat `gpu_id` as a current-impl detail; prefer `worker_id` (already
exists, is stable identifier)
- When a worker actually spans multiple GPUs, add
`PoolAssignment.device_ids: list[int]` and let `gpu_id` be `device_ids[0]`
for backward compat
- Or rename to `gpu_id` → `device_id` with deprecation alias
**Effort:** Small (1 field rename + alias).
**Dependencies:** Driven by an actual future "one worker = many GPUs" use case. Don't act preemptively.
### Item #6: Audio attention quantization profile
**Why:** Today audio attn and FFN are bf16. If an audio-quant profile
is added to `NVFP4Config.fp4_layers`, update
[`test_basic_av_block_propagates_quant_config_to_all_children`](file:///home/william5lin/FastVideo/fastvideo/tests/ops/quantization/test_nvfp4_ltx2_wiring.py).
**Effort:** Small (one test + one config field).
### Item #7: Schema parity inventory cleanup
**Why:** A few internal-only fields are not exposed publicly:
- `PROMPT_HTTP_TIMEOUT_MS`
- `PROMPT_INITIAL_STAGE_TIMEOUT_MS`
- `PROMPT_TEMPERATURE`
- `PROMPT_MAX_COMPLETION_TOKENS`
- `PROMPT_AUTO_SLEEP_MS`
- `PROMPT_AUTO_TIMEOUT_MS`
- curated-presets file paths
These flow via env vars on `dreamverse-server` today. If
`fastvideo serve --config` becomes the canonical entrypoint, they need
typed homes.
**Effort:** Small-Medium.
### Item #8: Stale `apps/web/test-results/` directory
**Why:** Cosmetic. `.gitignore` entry hides it from `git status`, but
the dir has stale `.last-run.json` (45 bytes) from a prior Playwright
run.
**Action:** `rm -rf apps/web/test-results` whenever convenient.
**Effort:** Trivial.
### ~~Item #9~~ + ~~#10~~: Commit-message cleanups — ✅ Resolved 2026-05-04
Both items resolved during the `will/api_7.8` prep rebase. A targeted
conditional script (`/tmp/opencode/cleanup_subjects_v2.sh` — only amends
when text actually changes) ran across 33 commits, modified 6:
- **#9 fix**: extended the regex from `\[\d+\.\d+/n\]` to
`\[\d+(\.\d+)?/n\]` so single-digit prefixes match. PR 8's 3 commits
now read `[type] streaming: ...` instead of `[type] [8/n] Improve API: ...`.
- **#10 fix**: added second substitution `streaming: streaming X` →
`streaming: X`. PR 7.8 / 7.9 commits no longer have the duplication.
The conditional check skipped pre-commit-hook flakiness on no-op amends
(unlike the earlier first attempt). All affected commits verified clean
post-rebase.
### Item #11: Promote LTX-2 prompt orchestration to public (when 2nd consumer exists)
**Why:** Per Q-2 in [decisions-log.md](decisions-log.md) and D-13's
"missing alternative", the LTX-2-specific orchestration (locked
segments, segment_prompts JSON shape, rollout id/label, lenient JSON
parsing) currently stays Dreamverse-side per DR-1. If a second
LTX-2-style consumer appears (e.g. another video model with multi-segment
continuation needing the same prompt orchestration), promote this layer
to `fastvideo.entrypoints.streaming.prompt.ltx2_orchestration`.
**Action:** Wait for a second consumer to materialize. Until then, the
orchestration stays in Dreamverse's `_internal_compat.py` shim (DR-1).
**Effort:** Medium when triggered.
**Dependencies:** A second consumer.
---
## Recommended pull order
If you have unbounded time and want to maximize forward progress:
1. **D-8 verify** (10 min) — eliminates uncertainty
2. **D-12-A docstring** (trivial) — caveat the GpuPool API publicly
3. **Item #2 AbsMaxFP8** (S) — clears tech debt
4. **Item VPO video_position_offset_sec** (30 min) — unblocks PR 7.10 (since 7.6 has merged, this is now scoped to whatever consumer first reads the field)
5. **DR-1 + DR-2 Dreamverse migration** (M) — **now unblocked since PR #1258 merged**; replaces 1700+ LOC of local fork
6. **Item #4 layer_profile** (M) — closes Dreamverse quant escape hatch
7. **Item #1 build_app routes** (M-L) — closes FE-compat
8. **Item D generate_async** (L) — unlock PR; brings along D-12-B (run_async) + closes Q-5/Q-9/PR-7.5 TODOs
9. **Item #5 typed quant_config carrier** (L+L) — final form
10. **Items #6/#7/#8 + D-12-C/D-13-A/D-13-B + #11** — cleanup polish (#9, #10 resolved 2026-05-04)
If you have a specific user goal (e.g. "ship `BE_FLAVOR=fastvideo`
flavor end-to-end"), that goal dictates the order — read this list as a
menu, not a prescription.
---
## Verification gates per item
When implementing any item above, evidence required:
| Phase | Check |
|---|---|
| Build | `lsp_diagnostics` clean on changed files |
| Test | new + relevant existing tests pass; output captured |
| Manual QA | actually run the affected feature end-to-end (per AGENTS.md MANUAL_QA_MANDATE) |
| Regression | full `fastvideo/tests/api/` + `contract/` + relevant SSIM (if NVFP4 touch) |
For NVFP4 touches: re-run `test_nvfp4_ltx2_wiring.py` +
`test_typed_quant_flow.py` (CPU) + ideally a flashinfer-enabled path
test (manual, not in CI).
For Dreamverse-side items (DR-1, DR-2): re-run
`Dreamverse/apps/web/npx playwright test e2e/preset-prompt-generation.spec.ts`
end-to-end against the live BE+FE — this is the contract test that
exercises the prompt enhancer through a real session.
@@ -1,141 +0,0 @@
# PR Roadmap
Status of all 17 PRs in the FastVideo public API refactor + streaming
server upstream + Dynamo backend contract + post-deprecation cleanup.
For design rationale see [design.md](design.md). For streaming-specific
PRs (7.5-7.10) see [streaming-server.md](streaming-server.md). For NVFP4
work that runs parallel to this sequence see [quantization.md](quantization.md).
**Last updated:** 2026-05-05 (strategy reversal — single mega-PR #1288 replaces planned splits 7.10/8/LTX-2/NVFP4/post-fixes/agents_cleanup; see [decisions-log.md D-17](decisions-log.md#d-17)).
## Status legend
- ✅ **Landed on `origin/main`**
- 🟢 **Open / in flight** — branch exists, may have open PR
- 🟡 **Planned** — designed, not started
- 🔵 **Future** — deferred to post-PR-13 cleanup
## Landed PRs (0 → 7.7)
| # | PR | Status | Merge commit | Scope |
|---|---|---|---|---|
| 0 | #1218 [1/n] | ✅ | merged | Parity inventory + typed inference schema |
| 1 | #1218 [1/n] | ✅ | merged | Strict parser/validation/overrides + API tests |
| 2 | #1220 [2/n] | ✅ | merged | Typed `VideoGenerator` constructors + request path + compat |
| 3 | #1226 [3/n] | ✅ | merged | CLI/YAML-first typed config loading for `generate` and `serve` |
| 4 | #1234 [4/n] | ✅ | merged | Preset registry + presets for all 13 model families; `SamplingParam` moved to `fastvideo/api/`; `configs/sample/` deleted entirely |
| 5 | #1237 [5/n] | ✅ | merged | `ServeConfig.default_request` wired into stateless OpenAI server |
| 5.5 | (`5d1d71fc`) | ✅ | merged | Streaming server package skeleton, typed `StreamingConfig`/`GpuPoolConfig`/`PromptEnhancerConfig`/`PromptSafetyConfig`/`WarmupConfig`, `streaming-serve` CLI stub |
| 6 | #1239 [6/n] | ✅ | merged | LTX2 public preset + asset wiring + `gpu_pool.py` typed-kwarg translation |
| 7 | #1250 [7/n] | ✅ | merged | Typed LTX2 continuation state + streaming session store + blob store |
| **7.5** | **#1251** | ✅ | `95fd29e0` (merged 2026-04-26) | Streaming server skeleton (WebSocket + fMP4 + single generator). 8 commits. Deferred TODOs (per-step progress, mid-segment cancellation) carried forward to PR 7.10. |
| **7.6** | **#1257** | ✅ | `eb0a4152` (merged 2026-05-04) | GPU pool upstream + worker subprocess + two-segment warmup. 7 commits squashed. APPROVED by Eigensystem. See [decisions-log.md D-12](decisions-log.md#d-12) for the architectural review. |
| **7.7** | **#1258** | ✅ | `f673423b` (merged 2026-05-04) | Prompt enhancer with `LLMProvider` abstraction. Built-in providers: cerebras, groq. 3 commits squashed. **Public Literal does NOT include `cerebras_ifm`** — open-threads.md item DR-2 covers the gap. See [decisions-log.md D-13](decisions-log.md#d-13) for the architectural review. |
| **7.8** | **#1284** | ✅ | `eb3a3942` (merged 2026-05-04) | Streaming auxiliaries — `prompt/safety.py` (optional fasttext, lazy import), `prompt/rewrite.py`, `session_logger.py` (thread-safe JSONL), `mock_server.py` (build_mock_app + MockGenerator for FE dev). 730 LOC, 2 commits. See [decisions-log.md D-14](decisions-log.md#d-14). |
| **7.9** | **#1286** | ✅ | `2aaeee2a` (merged 2026-05-05) | Streaming router (multi-replica load balancer + WS proxy + `fastvideo router-serve` CLI). Squashed `cd76cf51 + 1ac1e732 + b0b7f59c + a152cb77` (router-polish second-pass; cherry-pick of `40e265b8` from `will/ltx2_sr_port`). See [decisions-log.md D-15](decisions-log.md#d-15) (structural review) + [D-16](decisions-log.md#d-16) (second-pass polish). |
## In flight (mega-PR #1288)
| # | PR | Status | Branch | Scope |
|---|---|---|---|---|
| **mega** | **#1288** | 🟢 OPEN, MERGEABLE | `will/ltx2_sr_port` (head `b36bdbc9`) | **Single consolidated landing of the full `will/ltx2_sr_port` chain.** Was originally planned as 6 stacked PRs (slices 1-3 / 4-6 / 7-15 / 16-21 / 22-23 / 24-34). Now landing as one PR — see [decisions-log.md D-17](decisions-log.md#d-17) for the strategy decision. **Contents** (commit-ordered): (1) streaming `generate_async` + `VideoEvent` + Dynamo backend contract (3 commits, was PR 7.10/#1287 closed); (2) server contract docs + Dreamverse/Dynamo shape tests (3 commits, was PR 8); (3) LTX-2 SR runtime port + i2v conditioning + alignment harness (9 commits); (4) NVFP4 wire-up + per-component compile + typed `transformer_quant` flow (6 commits); (5) LTX-2 post-handoff parity fixes — Gemma `to()`, list-of-generators (2 commits); (6) `.agents/memory/dreamverse-integration/` knowledge base + agents Phase 1 cleanup (11 commits). 34 commits total, 71 files, +13,074/-583 LOC. |
## Closed PRs in this scope
| # | PR | Status | Why closed |
|---|---|---|---|
| **7.10** | **#1287** | ❌ CLOSED 2026-05-05 | Superseded by mega-PR #1288 — strategy reversal to land everything in one go. Same 3 commits now form the head of #1288. |
## Deprecated split bookmarks (D-17)
`will/api_7.10` / `will/api_8` / `will/ltx2_sr_runtime` / `will/ltx2_nvfp4` / `will/ltx2_post_fixes` / `will/agents_cleanup` were the split-PR bookmarks under the abandoned 6-PR plan. They remain locally as historical references but are no longer maintained. STACK.md (top-level) is similarly deprecated.
## Planned (post-#1288 merge)
| # | Status | Branch | Scope |
|---|---|---|---|
| 9 | 🟡 | — | LongCat preset migration + colocation (9 model-specific stage files) |
| 10 | 🟡 | — | Hunyuan15 SR preset migration + colocation + SR field migration POC |
| 11 | 🟡 | — | SSIM/performance test migration off legacy `generate_video(..., **kwargs)` |
| 12 | 🟡 | — | Docs + examples migration (includes streaming server + Dynamo) |
| 13 | 🟡 | — | Deprecation cleanup (includes flat LTX2 kwargs the internal `gpu_pool.py` used to consume) |
## Future (compat.py death sequence)
After PR 13 lands deprecation warnings, `fastvideo/api/compat.py` (~370
lines) is the last translation shim between typed public API and legacy
internals (`FastVideoArgs`, `SamplingParam`).
| # | Status | Scope | Lines removed |
|---|---|---|---|
| 14 | 🔵 reachable | Strip forward translation: `legacy_from_pretrained_to_config`, `legacy_generate_call_to_request`, `_sampling_param_to_request_raw`, `_LEGACY_REQUEST_ALIASES`, `_LTX2_REFINE_FLAT_KEYS`. Depends on PRs 11/12/7.6 callers being migrated. | ~100 |
| 15 | 🔵 | `FastVideoArgs` becomes a `@dataclass` view over `GeneratorConfig` with `@property` accessors backing legacy field names. ~600-line god-object refactor. Depends on PR 14. | reverse-translation half (~150) trivial |
| 16 | 🔵 | `ForwardBatch` reads `GenerationRequest` by reference; kills `request_to_sampling_param` and the `ForwardBatch(**shallow_asdict(sampling_param), …)` spread. `SamplingParam` demoted or deleted. Depends on PR 15. | rest |
| 17 | 🔵 | Move `normalize_generator_config`, `normalize_generation_request`, `load_generator_config_from_file` to `parser.py`. Delete `compat.py`. | file gone |
PRs 15-17 touch training, distributed, and worker code in addition to
inference path; realistically 1-2 quarters beyond the current plan.
## Dependency chain
```
PR 13 (deprecation)
↓
PRs 11, 12, 7.6 (migrate callers)
↓
PR 14 (forward translation gone) ─── ~100 lines out of compat.py
↓
PR 15 (FastVideoArgs as view) ─── reverse-translation trivial
↓
PR 16 (ForwardBatch reads request) ─── SamplingParam demoted
↓
PR 17 (move normalizers, delete file)
```
## NVFP4 work (out-of-band, parallel to PR 7.5+)
NOT in the canonical PR sequence. Lives on `will/ltx2_sr_port`
(currently @ `156103b9`) — a separate stack alongside the public-API
upstreaming. See [quantization.md](quantization.md) for what each commit
locks in.
| Commit range | Topic |
|---|---|
| `cfccd292..b6ac7630` | LTX-2 i2v + SR runtime port + alignment harness |
| `a4760bae..c6c14c55` | NVFP4 LTX-2 wire-up + per-component compile + parity fixes (May 2 handoff) |
| `a5fcd19c..156103b9` | Post-handoff parity/perf fixes |
## Key landed artifacts (reference points)
- Parity inventory: [`docs/design/inference_schema_parity_inventory.yaml`](file:///home/william5lin/FastVideo/docs/design/inference_schema_parity_inventory.yaml) + guard [`fastvideo/tests/api/test_schema_parity_inventory.py`](file:///home/william5lin/FastVideo/fastvideo/tests/api/test_schema_parity_inventory.py)
- Typed schema: [`fastvideo/api/schema.py`](file:///home/william5lin/FastVideo/fastvideo/api/schema.py)
- Compat layer: [`fastvideo/api/compat.py`](file:///home/william5lin/FastVideo/fastvideo/api/compat.py)
- Preset system: [`fastvideo/api/presets.py`](file:///home/william5lin/FastVideo/fastvideo/api/presets.py) + per-family `pipelines/basic/<family>/presets.py`
- Streaming package skeleton (PR 5.5): [`fastvideo/entrypoints/streaming/`](file:///home/william5lin/FastVideo/fastvideo/entrypoints/streaming/)
- LTX2 typed continuation state (PR 7): [`fastvideo/pipelines/basic/ltx2/continuation.py`](file:///home/william5lin/FastVideo/fastvideo/pipelines/basic/ltx2/continuation.py)
## Known notable decisions carried forward
- **Public inference boundary stays plain dataclasses + plain dict/YAML/JSON**
— not OmegaConf, not runtime config wrappers.
- **Every public entrypoint normalizes into typed config objects** before
touching legacy `FastVideoArgs` or `SamplingParam`.
- **Legacy `generate_video(..., **kwargs)` stays on direct legacy execution
path until PR 11**'s SSIM/performance migration. Prevents golden
baselines from drifting during compat period.
- **Typed requests use schema defaults**; legacy `generate_video(...)`
continues to inherit model-specific `SamplingParam` defaults during
compat period.
- **Preset registry uses explicit `_register_presets()` pattern** matching
`_register_configs()`; lookup keyed by `model_family`.
- **Stateless OpenAI server clones `ServeConfig.default_request`** and
merges user overrides; preset validation runs before legacy generation.
- **Streaming server added as sibling `fastvideo/entrypoints/streaming/`**
rather than extending `fastvideo/entrypoints/openai/` (PR 5.5).
## Per-PR commit-level detail
For per-PR commit lists, test plans, and merge criteria, the archived
source [`source-archive/PR-plan.md`](source-archive/PR-plan.md) (1145 lines)
remains the deepest reference. This file is the navigable summary.
@@ -1,229 +0,0 @@
# Quantization — NVFP4, LinearBase Fallback, Layer Profiles
What landed in the May 2 NVFP4 stack, why it's load-bearing, and what's
still owed (`layer_profile`, typed quant carrier, AbsMaxFP8 cleanup).
For overall API design see [design.md](design.md). For the open
follow-ups see [open-threads.md](open-threads.md).
**Last updated:** 2026-05-03.
## NVFP4 — what it is
NVIDIA's specific block-scaled FP4 format:
- e2m1 mantissa
- fp32 alpha
- `layout_128x4` scale layout
- group size 16
Distinct from MX-FP4 / OCP-FP4 / generic e3m0. The May 2 rename
(`94c983a2`) disambiguated the naming throughout FastVideo's public
surface.
## Files (current)
| File | Role |
|---|---|
| [`fastvideo/layers/quantization/nvfp4_config.py`](file:///home/william5lin/FastVideo/fastvideo/layers/quantization/nvfp4_config.py) | `NVFP4Config`, `NVFP4QuantizeMethod`, `convert_model_to_nvfp4` |
| [`fastvideo/layers/quantization/__init__.py`](file:///home/william5lin/FastVideo/fastvideo/layers/quantization/__init__.py) | `QuantizationMethods` literal includes `"NVFP4"`; `get_quantization_config` resolves it |
| [`fastvideo/layers/linear.py`](file:///home/william5lin/FastVideo/fastvideo/layers/linear.py) | `LinearBase.__init__` falls back to `UnquantizedLinearMethod` when `quant_config.get_quant_method` returns None — **load-bearing** |
| [`fastvideo/models/loader/fsdp_load.py`](file:///home/william5lin/FastVideo/fastvideo/models/loader/fsdp_load.py) | `_maybe_convert_model_to_nvfp4` helper detects via `isinstance(quant_method, NVFP4QuantizeMethod)`; calls `convert_model_to_nvfp4` to materialize buffers |
| [`fastvideo/models/dits/ltx2.py`](file:///home/william5lin/FastVideo/fastvideo/models/dits/ltx2.py) | `nn.Linear` → `ReplicatedLinear` for FP4-eligible subset; `_supports_prequantized_input` + `_linear_project_with_optional_prequant` helpers; quant_config + prefix= plumbing |
| [`fastvideo/api/compat.py`](file:///home/william5lin/FastVideo/fastvideo/api/compat.py) | Typed `engine.quantization.transformer_quant: "NVFP4"` resolves to `NVFP4Config()` instance |
| [`fastvideo/fastvideo_args.py`](file:///home/william5lin/FastVideo/fastvideo/fastvideo_args.py) | `__post_init__._apply_transformer_quant` pins `pipeline_config.dit_config.quant_config = NVFP4Config()` |
## Buffer naming (post-rename)
| Old | New |
|---|---|
| `_fp4_weight` / `_fp4_alpha` | `_nvfp4_weight` / `_nvfp4_alpha` |
| `_weight_global_sf` | unchanged |
| `convert_model_to_fp4` | `convert_model_to_nvfp4` |
| `FP4QuantizeMethod` | `NVFP4QuantizeMethod` |
| `QuantizationMethods` literal `"FP4"` | `"NVFP4"` |
Internal-scope torch op namespace `fastvideo_fp4::*` and
`_get_ltx2_fp4_stage_profile` deliberately left as-is — purely internal
naming that mirrors FastVideo-internal.
## Layer set asymmetry — by design
`NVFP4Config.fp4_layers` (default `layer_profile="refine"`) covers:
- `attn1.{to_q,to_k,to_v,to_out}` — full self-attention
- `attn2.{to_q,to_out}` — cross-attn Q + out only (text context not quantized)
- `audio_to_video_attn.{to_q,to_out}` — AV cross Q + out
- `video_to_audio_attn.{to_k,to_v}` — VA cross K + V
- `ffn.{fc_in,fc_out}` — video FFN
- `adaln_single.linear` — but this is `nn.Linear` (not `LinearBase`),
so it never actually gets FP4'd. List entry has no effect; matches
internal.
**NOT in the set:**
- audio self-attention (`audio_attn1.*`)
- audio cross-attention (`audio_attn2.*`)
- audio FFN (`audio.ffn.*`)
Audio path is cheap enough that quant overhead isn't worth it. Test
[`test_basic_av_block_propagates_quant_config_to_all_children`](file:///home/william5lin/FastVideo/fastvideo/tests/ops/quantization/test_nvfp4_ltx2_wiring.py)
locks this in — if you add audio quantization later, update the test.
## `LinearBase` fallback — DO NOT REMOVE
[`fastvideo/layers/linear.py:191-202`](file:///home/william5lin/FastVideo/fastvideo/layers/linear.py#L191-L202): when `quant_config.get_quant_method` returns
`None` (layer not in the quant config's set), we fall back to
`UnquantizedLinearMethod`.
**Removing this fallback would break every non-tagged
`ReplicatedLinear` constructed with an `NVFP4Config`** — the previous
`assert quant_method is not None` would crash on unmatched layers (e.g.
text-encoder K/V projections, audio attention, etc.).
This is one of the load-bearing changes from `42b30bf9`.
## `transformer_quant` precedence rules
`FastVideoArgs._apply_transformer_quant` only writes
`dit_config.quant_config` when it's currently `None`. **If a caller has
explicitly set** `pipeline_config.dit_config.quant_config = NVFP4Config(...)`,
the explicit setter wins.
Dreamverse's `video_generation.py` relies on this precedence — it sets
`NVFP4Config()` directly via `experimental["pipeline_config"]` because
typed `transformer_quant: "NVFP4"` doesn't yet expose `layer_profile`.
See "Open follow-ups" below.
## Attention forward optimization
[`models/dits/ltx2.py`](file:///home/william5lin/FastVideo/fastvideo/models/dits/ltx2.py)
ports `_supports_prequantized_input` and
`_linear_project_with_optional_prequant`. Attention forward
pre-quantizes input once (`quantize_input`), reuses the
`(x_fp4, x_scale, x_global_sf)` tuple for k/v projections when
`context is x` — bit-matches internal's fused path.
## `prepare_for_compile` protocol
[`composed_pipeline_base._maybe_compile_pipeline_module`](file:///home/william5lin/FastVideo/fastvideo/pipelines/composed_pipeline_base.py)
calls `getattr(module, "prepare_for_compile", None)` before invoking
`torch.compile`. Defined as a duck-type protocol — no base class method.
Currently only **Gemma3** implements it (to materialize HF weights
outside Dynamo's tracer). Add to other models that have lazy external
state if you observe compile-time graph breaks.
## Per-component compile flags
`CompileConfig` (in
[`fastvideo/api/schema.py`](file:///home/william5lin/FastVideo/fastvideo/api/schema.py))
gained per-component knobs in `221cb20a`:
```python
@dataclass
class CompileConfig:
enabled: bool = False # master DiT switch
backend: str = "inductor"
fullgraph: bool = False
mode: str | None = None
dynamic: bool | None = None
extras: dict = field(default_factory=dict)
# Per-component overlays, None = inherit master `enabled`
text_encoder_enabled: bool | None = None
vae_enabled: bool | None = None
audio_vae_enabled: bool | None = None
# Per-component kwargs override master when non-empty
dit_kwargs: dict = field(default_factory=dict)
text_encoder_kwargs: dict = field(default_factory=dict)
vae_kwargs: dict = field(default_factory=dict)
audio_vae_kwargs: dict = field(default_factory=dict)
```
**`transformer_refine` is auto-compiled with the master DiT flag.** No
separate `enable_torch_compile_refine` flag — by design, refine inherits
DiT compile state to keep typed surface small. Decoupling would add a
new flag, not repurpose existing ones.
## Quantization commit chain (`will/ltx2_sr_port`)
| Commit | Locks in |
|---|---|
| `365a66c7 feat(quantization): upstream LTX-2 FP4Config with lazy flashinfer` | Public colocation of FP4Config (resolves dreamverse_review Q-6 option 1); flashinfer lazy-imported in loader helper, no public hard-dep |
| `a4760bae fix(api): propagate generic refine_*` | `_resolve_refine_args()` copies generic `refine_*` knobs onto `ltx2_refine_*` runtime carriers; `_randn_ltx2_video_latents` reverts to `torch.randn` to bit-match internal under single-generator inference |
| `221cb20a feat(api): typed per-component CompileConfig` | `CompileConfig` per-component knobs; matching `FastVideoArgs` carriers; compat layer round-trip |
| `6da342ba feat(compile): per-component compile + transformer_refine + prepare hook` | `composed_pipeline_base.post_init` compiles `transformer_refine` alongside `transformer`/`transformer_2`; per-component compile loops; `prepare_for_compile` hook on Gemma3 |
| `42b30bf9 feat(ltx2): wire FP4 inference` (largest) | `nn.Linear` → `ReplicatedLinear` for FP4-eligible LTX2 subset; `quant_config` + `prefix=` plumbing; `_maybe_convert_model_to_nvfp4` helper; `LinearBase` fallback to `UnquantizedLinearMethod`; typed `transformer_quant` resolution |
| `94c983a2 refactor(quant): rename FP4 → NVFP4` | Mechanical rename across config, methods, buffers, tests |
| `c6c14c55 test(nvfp4): lock LTX-2 wiring + typed transformer_quant flow` | 6+4 tests in `test_nvfp4_ltx2_wiring.py` + `test_typed_quant_flow.py` |
| `a5fcd19c [fix]: lazy-import flash_attn 2 fallback in attention backend` | post-handoff: lazy import to avoid hard flash_attn 2 dep |
| `d4ee5be2 [fix]: avoid model.to() round-trip in Gemma encoder forward` | post-handoff: parity / perf fix |
| `156103b9 [fix]: unwrap list-of-generator before torch.randn in LTX-2 latent prep` | post-handoff: parity fix for list-of-generators (was bit-matching only single-generator path) |
## Tests
| Test | Asserts |
|---|---|
| [`fastvideo/tests/ops/quantization/test_nvfp4_ltx2_wiring.py`](file:///home/william5lin/FastVideo/fastvideo/tests/ops/quantization/test_nvfp4_ltx2_wiring.py) (6 tests) | `LTXSelfAttention.to_q/to_k/to_v/to_out` are `ReplicatedLinear`; `NVFP4Config()` attaches `NVFP4QuantizeMethod` on the quantized subset with correct `layer_prefix`; non-tagged projections (cross-attn K/V, audio attn, audio FFN) fall back to `UnquantizedLinearMethod`; `BasicAVTransformerBlock` propagates `quant_config`+`prefix` correctly to all 4 attention modules + FFN |
| [`fastvideo/tests/api/test_typed_quant_flow.py`](file:///home/william5lin/FastVideo/fastvideo/tests/api/test_typed_quant_flow.py) (4 tests) | typed `engine.quantization.transformer_quant: "NVFP4"` → `NVFP4Config()` instance flow; default leaves `transformer_quant` None; explicit `dit_config.quant_config = ...` wins over typed carrier |
CPU-only by design; do NOT exercise actual FP4 kernels (no flashinfer in
CI). Real kernel coverage requires a CI run with flashinfer installed.
## Open follow-ups (quantization-specific)
### #4: Expose `layer_profile` on typed `engine.quantization`
Today `transformer_quant: "NVFP4"` always constructs `NVFP4Config()`
with default `layer_profile="refine"`. To support stage-1 profiles (no
`attn2.to_out`, no cross-modal AV) via typed config, add
`transformer_quant_layer_profile: str | None = None` and thread it
through:
- `fastvideo/api/schema.py` — `QuantizationConfig` field
- `fastvideo/api/compat.py` — typed → flat translation
- `fastvideo/fastvideo_args.py` — `_apply_transformer_quant` consumes it
Dreamverse currently dodges this by setting `NVFP4Config()` directly via
`experimental["pipeline_config"]`. Exposing `layer_profile` removes the
dodge. See [open-threads.md](open-threads.md) #4.
### #5: Typed `dit_config.quant_config` carrier (replace `experimental["pipeline_config"]`)
Long-term: design a typed home for an in-memory `PipelineConfig`
instance with mutated `dit_config`. Today `compat.py` recognizes the
`pipeline_config` key in `experimental` and threads it through to
`FastVideoArgs.from_kwargs`. This is fine for short-term but not pretty.
Heaviest design work in the open queue. May need Oracle consult.
### #2: AbsMaxFP8 pre-existing test failure
`fastvideo/tests/ops/quantization/test_absmax_fp8.py::test_create_weights_rejects_invalid_dtype`
fails on `main` and on `will/ltx2_sr_port` with the same error
(`AssertionError not raised`). Verified via `git stash` that the
failure pre-dates NVFP4 work.
Either:
- Fix the test (`AbsMaxFP8LinearMethod.create_weights` no longer
asserts on invalid dtype — restore the assert if intentional, or drop
the test).
Self-contained tech debt; small fix.
## Don't / Cautions
- **Don't change `NVFP4Config` buffer names back to `_fp4_*`.** Rename
is intentional to disambiguate from MX-FP4 / OCP-FP4.
- **Don't remove the `LinearBase` `UnquantizedLinearMethod` fallback.**
Load-bearing for non-tagged layers when a `quant_config` is set.
- **Don't repurpose `enable_torch_compile` to mean DiT-only.** It also
drives `transformer_refine` and `transformer_2` compile.
- **Don't bypass the typed surface for new options.** New compile /
quant / refine knobs should land on the dataclass + compat.py +
parity inventory together. The existing test suite locks this in.
- **Don't merge to main without a CI run that covers FP4.** Current CI
doesn't run flashinfer-dependent paths; the wiring tests are CPU-only
by design.
@@ -1,385 +0,0 @@
# Runbook — How to Do Work in This Scope
Operational how-to for the dreamverse-integration scope. Read after
[state.md](state.md) and [open-threads.md](open-threads.md).
For design rationale see [design.md](design.md). For who to credit see
[authors.md](authors.md). For PR status see [pr-roadmap.md](pr-roadmap.md).
**Last updated:** 2026-05-05 (strategy reversed to single mega-PR #1288 on `will/ltx2_sr_port`; #1287 closed; STACK.md split model deprecated per [decisions-log.md D-17](decisions-log.md#d-17)).
## Worktree contract
```
Repo: /home/william5lin/FastVideo
Branch: will/ltx2_sr_port
```
Other agents and the user share this worktree concurrently. If `git status`
shows changes you don't recognize, they belong to **someone else's work** —
don't revert, don't `git stash drop`, don't `git checkout -- <file>`.
Switch to `will/ltx2_sr_port` cleanly with `git checkout will/ltx2_sr_port`
(safe if your own working tree is clean) and proceed.
If your task requires a different branch (e.g. cherry-pick to
`will/api_7.9` for PR #1286 propagation), return to `will/ltx2_sr_port`
when done — that is the assumed default.
## Branch topology (single mega-PR model)
The dreamverse-integration work now ships as one PR (#1288) off
`will/ltx2_sr_port`. The split-PR model documented in earlier revisions
of this runbook (and in top-level `STACK.md`) is **abandoned** —
see [decisions-log.md D-17](decisions-log.md#d-17).
```
origin/main
↓ [public-API refactor: PRs 0..7.9 merged on main, latest #1286 = 2aaeee2a]
will/ltx2_sr_port (**PR #1288 head** — single mega-PR, 34 commits, 71 files, +13,074/-583)
```
| Branch | Role | Status |
|---|---|---|
| `will/ltx2_sr_port` | **PR #1288 head**, default working branch | OPEN, MERGEABLE |
| `will/api_7.10` / `will/api_8` / `will/ltx2_sr_runtime` / `will/ltx2_nvfp4` / `will/ltx2_post_fixes` / `will/agents_cleanup` | deprecated split-PR bookmarks | local-only historical references; safe to delete |
| `will/ltx2_sr_port-pre-1286-rebase` | safety backup | local-only; preserves the 4 commits dropped during the post-#1286 rebase |
**Sanity check:** `git merge-base --is-ancestor origin/main will/ltx2_sr_port`
should exit 0. If it doesn't, the branch is in an unexpected state — read
[state.md](state.md) before continuing.
## After PR #1288 merges
When the mega-PR squash-merges into `main`:
1. `git fetch origin main` to pull the merge commit.
2. The entire `will/ltx2_sr_port` content is now on main; the branch can
be deleted (locally + on origin) once all consumers are notified.
3. Delete deprecated split bookmarks: `git branch -D will/api_7.10
will/api_8 will/ltx2_sr_runtime will/ltx2_nvfp4 will/ltx2_post_fixes
will/agents_cleanup` (local-only, no remote).
4. Optionally remove top-level `STACK.md` (now a historical artifact).
Keep `CO-AUTHORS.md` — still the canonical roster reference.
5. Decide whether to keep `will/ltx2_sr_port-pre-1286-rebase` (safety
backup of the pre-rebase chain) — recommend deleting once #1288 is
merged and verified on main.
6. Update memory dir to reflect the post-merge state — bump
`Last reconciled` headers, mark Item D resolved in
[open-threads.md](open-threads.md), record the merge commit in
[decisions-log.md](decisions-log.md).
## Historical: split-PR re-slice protocol (deprecated)
Prior revisions of this runbook documented a 10-step re-slice protocol
for the abandoned 6-PR split model. That protocol is now obsolete.
The post-#1286 rebase (2026-05-05) was the last execution of it; details
are preserved in [state.md](state.md) "Post-#1286 rebase summary" and
git history at commit `b34d9704`.
## Verification
### Lint (pre-commit)
```bash
pre-commit run --files <changed-paths...>
```
- Binary: `/home/william5lin/miniconda3/envs/fv-main/bin/pre-commit`.
NOT `.venv/bin/pre-commit` — that doesn't exist in this worktree.
- Auto-applies yapf reformatting; re-stage modified files after.
- Hook chain: yapf → ruff → codespell → mypy → spaces-check.
- Memory dir (`.agents/memory/`) is yapf/ruff/mypy excluded — only
"spaces" runs. Memory edits don't need lint, but DO use UTF-8 and
consistent line endings.
### Tests
Router tests (PR #1286 scope):
```bash
.venv/bin/python -m pytest fastvideo/tests/entrypoints/streaming/test_router.py -v --no-header
```
Stack baseline (May 2 handoff suite — re-run when you change anything in
api/, contract/, or LTX-2 paths):
```bash
.venv/bin/python -m pytest \
fastvideo/tests/api/ \
fastvideo/tests/contract/ \
fastvideo/tests/ops/quantization/test_nvfp4_*.py \
tests/local_tests/pipelines/test_ltx2_pipeline_smoke.py \
-q --no-header
```
Expected baselines:
- May 2 handoff (`156103b9`): 222 passed, 1 skipped.
- Post-D-16 (`a152cb77` / `09647a30`): +7 router tests pass on top.
### LSP
Use `lsp_diagnostics` on changed files BEFORE running build. Pre-existing
warnings to ignore (predate this work):
- `fastvideo/entrypoints/streaming/router/main.py:37` — `Task` generic.
- `fastvideo/entrypoints/cli/router_serve.py:55` — `_SubParsersAction` generic.
### gh CLI for PR status
```bash
# PR #1286 quick status
gh pr view 1286 --json headRefOid,mergeable,statusCheckRollup \
--jq '{headRefOid, mergeable, checks: [.statusCheckRollup[] | {name, status, conclusion}]}'
# All commits in a PR + co-author check
gh pr view 1286 --json commits \
--jq '.commits[] | {oid: .oid[0:8], msg: .messageHeadline, author: .authors[0].login}'
```
## Commit workflow
### Subject convention
`[type] <scope>: <imperative summary>` — keep ≤ 72 chars.
Types observed in this scope: `feat`, `fix`, `test`, `docs`, `chore`,
`refactor`. Scopes observed: `streaming`, `dreamverse-integration`,
`api`, `quant`, `ltx2`, `nvfp4`, etc.
Examples:
- `[fix] streaming: router polish — bridge cancel + state machine + deps`
- `[docs] dreamverse-integration: add authors.md + track D-16 router polish`
### Body convention
Bullet list, one bullet per file or concern. Why-before-what. Wrap at
~80 chars (yapf doesn't reformat commit messages; readability is on you).
### Co-author trailers (REQUIRED on every commit)
The 4 trailers in [authors.md](authors.md) MUST appear on every commit
in this scope. Use `--trailer` flags or write the body to a file with
`-F` — DO NOT use multiple `-m` blocks for the trailers (each `-m` is
its own paragraph and git's trailer parser only reads the LAST paragraph,
yielding 1 trailer parsed instead of 4).
**Inline `--trailer` form (preferred for short commits):**
```bash
git commit -m "subject" -m "body..." \
--trailer "Co-authored-by: Junda (David) Su <90978028+Davids048@users.noreply.github.com>" \
--trailer "Co-authored-by: Matthew Noto <99706358+RandNMR73@users.noreply.github.com>" \
--trailer "Co-authored-by: XOR-op <17672363+XOR-op@users.noreply.github.com>" \
--trailer "Co-authored-by: Zhang Peiyuan <42993249+jzhang38@users.noreply.github.com>"
```
**File form (preferred for multi-paragraph bodies):**
```bash
cat > /tmp/opencode/msg.txt <<'EOF'
[type] scope: subject
* Bullet one with rationale.
* Bullet two with rationale.
Co-authored-by: Junda (David) Su <90978028+Davids048@users.noreply.github.com>
Co-authored-by: Matthew Noto <99706358+RandNMR73@users.noreply.github.com>
Co-authored-by: XOR-op <17672363+XOR-op@users.noreply.github.com>
Co-authored-by: Zhang Peiyuan <42993249+jzhang38@users.noreply.github.com>
EOF
git commit -F /tmp/opencode/msg.txt
```
The trailers MUST be a single block at the end of the message with no
blank lines between them.
**Verify trailers parsed:**
```bash
git log -1 --format='%(trailers:key=Co-authored-by,valueonly)'
```
Should print 4 lines (one per author). If only 1 line, you have the
multi-`-m` bug — amend with `-F` to fix (allowed if commit is unpushed
and you authored it in this session per AGENTS.md amend rules).
### NEVER add to commits
Per [`AGENTS.md`](../../../AGENTS.md):
- AI co-authors (Claude, GPT, Codex, Cursor, etc.) — explicitly forbidden
- "Generated with Claude Code" footer — explicitly forbidden
- `--no-verify` to skip pre-commit — explicitly forbidden
## Push + PR propagation
### Pushing `will/ltx2_sr_port` (top of stack)
```bash
git push origin will/ltx2_sr_port # fast-forward, no force needed
```
If git wants to force-push, you've rewritten history. STOP and verify:
```bash
git log origin/will/ltx2_sr_port..will/ltx2_sr_port # local-only commits
git log will/ltx2_sr_port..origin/will/ltx2_sr_port # remote-only commits
```
Force-push requires explicit user confirmation per `AGENTS.md`.
### Propagating fixes to PR #1286 (`will/api_7.9`)
When a fix is in router code (`fastvideo/entrypoints/streaming/router/`,
`cli/router_serve.py`, `tests/entrypoints/streaming/test_router.py`,
or `pyproject.toml` router-related), it must land on BOTH branches.
Cherry-pick avoids any force-push:
```bash
# 1. Commit on will/ltx2_sr_port first (working branch)
git add <files...>
git commit -F /tmp/opencode/msg.txt # with trailers per above
# 2. Cherry-pick onto will/api_7.9 (creates a separate SHA, identical diff)
git checkout will/api_7.9
git cherry-pick <ltx2_sr_port-sha>
git push origin will/api_7.9 # fast-forward, no force
# 3. Return to working branch
git checkout will/ltx2_sr_port
# 4. Verify PR #1286 picked it up
gh pr view 1286 --json headRefOid --jq '.headRefOid'
```
Two SHAs for the same diff — they'll dedupe naturally on the next
bulk-rebase via the trailer-injection rebase command in
[authors.md](authors.md).
### When a fix is memory-dir-only
`.agents/memory/dreamverse-integration/` lives in the `agents_cleanup`
layer of the stack — it does NOT belong on `will/api_7.9`. Memory updates
stay on `will/ltx2_sr_port` only.
### When a fix is non-router code in the integration scope
Land on `will/ltx2_sr_port`. If that fix needs to ship as a separate PR
(e.g. extending PR 7.10 or starting PR 9), open a new branch off the
right base per [pr-roadmap.md](pr-roadmap.md).
## Memory dir maintenance
When state changes, update the memory dir BEFORE moving on. Every file
has a "Last updated" header — bump when you edit.
| Change | File to update |
|---|---|
| Branch tip moves | [state.md](state.md) "Branch tips" + "Last reconciled" |
| PR opens / merges | [pr-roadmap.md](pr-roadmap.md) status table |
| New decision made | [decisions-log.md](decisions-log.md) — add D-N entry, bump header |
| Open thread resolved | [open-threads.md](open-threads.md) — strikethrough + "Resolved" note |
| New open thread | [open-threads.md](open-threads.md) — priority overview + section |
| New collaborator credited | [authors.md](authors.md) roster + trailer block + bulk-rebase |
| Source doc archived | [source-archive/README.md](source-archive/README.md) + [README.md](README.md) sources table |
| Process / runbook detail changes | [runbook.md](runbook.md) (this file) |
Cross-link siblings via relative paths. Never duplicate content — link.
## Common pitfalls
### `pre-commit` not in `.venv/bin`
`pre-commit` lives at `/home/william5lin/miniconda3/envs/fv-main/bin/pre-commit`.
The `.venv` here is for the FastVideo package itself, not pre-commit.
### Trailers split across paragraphs
`git commit -m A -m B -m C` makes A, B, C separate paragraphs. Git's
trailer parser only reads the LAST paragraph — multiple `-m
"Co-authored-by: ..."` produces 1 trailer parsed, not 4. Use `--trailer`
flags or `-F` with the trailers in a single block at the end.
### Stash 0 on FastVideo IS NOT yours
`stash@{0}: WIP on main: 71bfc13d HunyuanVideo plugin` predates this work.
**DO NOT POP.** See [state.md](state.md) "Stashes — DO NOT POP".
### `AbsMaxFP8` test "failure" is pre-existing
`fastvideo/tests/ops/quantization/test_absmax_fp8.py::test_create_weights_rejects_invalid_dtype`
fails on `main` and on every branch in this scope. NOT introduced by
integration work. See [open-threads.md](open-threads.md) item #2.
### Untracked nested clones at repo root
`dynamo/`, `ray/`, `vllm-omni/` are untracked nested git clones at the
FastVideo repo root. Reference repos for cross-repo work. **Do not
`rm -rf`** — they're someone else's working state.
### Live services on 8009 / 5274
`dreamverse-server` runs on 8009 (warmed GPU worker), Next.js dev server
on 5274. Don't start new instances on those ports without checking
[state.md](state.md) "Live services" first.
### Branch may have been switched by another agent
Other agents share this worktree. If `git branch --show-current` returns
something other than `will/ltx2_sr_port`, switch back cleanly with
`git checkout will/ltx2_sr_port` — don't disturb their work, don't
discard their uncommitted changes.
### Force-push policy
Per `AGENTS.md`: never force-push without explicit user confirmation.
For trailer fixes on already-pushed commits, prefer the bulk-rebase
command in [authors.md](authors.md) — safe to re-run.
### Two trailerless commits in PR #1286
`a152cb77` (on `will/api_7.9`) and `40e265b8` (now-superseded ancestor
on `will/ltx2_sr_port`) lack the 4 co-author trailers. **Accepted gap**
per user decision — see [authors.md](authors.md) "Known gaps".
## Self-test (verify your context is loaded)
After reading the memory dir, you should be able to answer:
1. What branch should I be on? → `will/ltx2_sr_port`
2. What's the active open PR in this scope? → #1286 on `will/api_7.9`
3. Where does PR #1286 land in the stack? → Bottom; ancestor of `will/ltx2_sr_port`
4. Who do I credit on every commit? → 4 authors per [authors.md](authors.md)
5. Where do memory updates land? → `will/ltx2_sr_port` only (NOT api_7.9)
6. What's the next-priority open thread? → See [open-threads.md](open-threads.md) "Recommended pull order" — D-8 verify is current top
7. What pre-existing failure can I ignore? → AbsMaxFP8 test (item #2)
8. What's the bulk-rebase command for adding trailers across the stack? → See [authors.md](authors.md) "How the trailers were applied"
If you can't answer one of these from the memory dir alone, the dir has
a gap — file it as a new entry in [open-threads.md](open-threads.md)
before continuing.
## First 60 seconds — copy-paste orientation
```bash
# 1. Confirm branch
cd /home/william5lin/FastVideo
git branch --show-current # should print: will/ltx2_sr_port
# If not, recover: git checkout will/ltx2_sr_port
# 2. Confirm worktree clean (untracked nested clones expected)
git status --short
# 3. Confirm PR #1286 head matches expected api_7.9 tip
gh pr view 1286 --json headRefOid --jq '.headRefOid'
git rev-parse will/api_7.9 # should match PR head
# 4. Confirm your context vs the memory dir
git log -1 --oneline
cat .agents/memory/dreamverse-integration/state.md | head -30
# 5. Confirm live services still running
curl -s http://localhost:8009/readyz | head -c 200
curl -s http://localhost:5274/ -o /dev/null -w "%{http_code}\n"
```
If any of those produce unexpected output, read [state.md](state.md)
before changing anything.
File diff suppressed because it is too large Load Diff
@@ -1,44 +0,0 @@
# Source Archive
These are the original unsynthesized design and integration docs that
predate the consolidation in
[`../`](../). They are **NOT** the source of truth — the synthesized
sibling files in the parent directory are.
Archived 2026-05-03. All previously untracked.
## Contents
| File | Original location | Date | Synthesized into |
|---|---|---|---|
| `apirefactor.md` | `FastVideo/` (repo root) | 2026-04-21 | [`../design.md`](../design.md) |
| `PR-plan.md` (was `PR plan.md` at repo root) | `FastVideo/` (repo root) | 2026-04-25 | [`../pr-roadmap.md`](../pr-roadmap.md) |
| `dreamverse_review.md` | `FastVideo/` (repo root) | 2026-04-26 | [`../decisions-log.md`](../decisions-log.md) + [`../state.md`](../state.md) |
| `handoff-nvfp4-launch-demo.md` | `.agents/exploration/` | 2026-05-02 | [`../state.md`](../state.md) + [`../quantization.md`](../quantization.md) + [`../open-threads.md`](../open-threads.md) |
| `streaming-server-upstream-plan.md` | `.agents/exploration/` | 2026-04-17 | [`../streaming-server.md`](../streaming-server.md) + [`../decisions-log.md`](../decisions-log.md) |
| `dreamverse_integration.md` | `.agents/exploration/` | 2026-04-23 | [`../cross-repo-surfaces.md`](../cross-repo-surfaces.md) |
| `video-generator-config-api-design.md` | `.agents/exploration/` | 2026-04-02 | [`../design.md`](../design.md) (early-draft material) |
## Why archived (not deleted)
- Future agents may want the **full unsynthesized rationale** for a
decision the synthesis abbreviated.
- The originals remain useful as a **time machine** for understanding
how the design evolved.
- These docs were never committed to git, so leaving them on disk costs
nothing.
## When to read the archive vs. the synthesis
- **Read the synthesis (`../*.md`)** for: current state, decision
status, action items, design rationale at the conceptual level.
- **Read the archive (here)** for: deep historical context, exact wording
of design decisions, full PR plan with all sub-PR commit details,
the original Q-1..Q-9 / D-1..D-11 prose.
## Maintenance rule
Do NOT edit files in this archive. They are point-in-time snapshots.
If new design material appears that supersedes an entry here, update the
synthesis (the parent dir) and append a note to that synthesis file —
do not mutate this archive.
@@ -1,838 +0,0 @@
# FastVideo API Refactor Design
## Related Documents
- [PR plan.md](PR%20plan.md) — PR-by-PR implementation plan for this design
- [.agents/exploration/streaming-server-upstream-plan.md](.agents/exploration/streaming-server-upstream-plan.md) — streaming-server upstream + Dynamo backend contract (shapes PRs 5.5-7.10)
- `../FastVideo-internal/.agents/exploration/rebase-upstream-fastvideo.md` — rebasing FastVideo-internal onto upstream (enables PRs 6-8)
- `../FastVideo-internal/ui/ltx2-streaming/` — source for the streaming server being upstreamed (PRs 7.5-7.9)
- `../dynamo/` — local clone of ai-dynamo/dynamo; `components/src/dynamo/sglang/` is the template for FastVideo's native backend landed in PR 7.10
- https://github.com/ai-dynamo/dynamo/pull/7544 — closed draft PR that establishes the Dynamo backend shape this design must satisfy
## Status
Design spec for the public inference API refactor. PRs 0-5.5 are landed; see [PR plan.md](PR%20plan.md) for rollout status and the PR 6+ roadmap. The typed schema, strict parser, preset system, typed VideoGenerator, typed CLI, and stateless OpenAI server default-request merge are all implemented. Streaming package skeleton + typed streaming config types are in place; live streaming server + Dynamo contract are the next milestones.
## Executive Summary
FastVideo should move to a single typed nested inference schema that is shared across:
- Python API
- CLI
- YAML/JSON config files
- OpenAI/server request translation
The core split is:
- `GeneratorConfig`: generator-instance lifetime settings
- `GenerationRequest`: per-call inputs, sampling, outputs, and continuation
- `InferencePreset`: model-owned named multi-stage defaults
The canonical user experience should be:
1. Choose a model.
2. Choose a pipeline preset.
3. Override a few typed fields.
4. Generate.
FastVideo should not make a raw free-form string dict the primary API. Dicts and YAML/JSON should be supported as serialization/interchange layers, but they must be parsed immediately into typed config objects with strict unknown-key validation.
The repo should also shift model-specific preset/default definitions closer to their pipeline implementations, while keeping the shared public schema and parsers centralized.
## Why This Refactor Is Needed
Today the public inference boundary is too flat and too forgiving.
- `VideoGenerator.from_pretrained(..., **kwargs)` mixes:
- engine/runtime settings
- pipeline init settings
- component overrides
- `VideoGenerator.generate_video(..., **kwargs)` mixes:
- prompt and inputs
- sampling parameters
- output settings
- model-specific workflow knobs
- unknown or drifting keys can be silently filtered or merely logged instead of failing fast
- model-specific multi-stage behavior is exposed through ad hoc top-level flags instead of a stable preset/stage abstraction
This is already painful in LTX2/Dreamverse, and it will get worse as more multi-stage pipelines are upstreamed.
## Design Goals
- Keep the Python API typed and editor-friendly.
- Make YAML/JSON a first-class serialization of the same schema.
- Support CLI overrides cleanly without flattening the schema into hundreds of canonical flags.
- Separate init-time config from request-time config.
- Provide a stable public abstraction for multi-stage pipelines.
- Support LTX2 two-stage and continuation behavior cleanly.
- Keep the simple case simple.
- Co-locate model-owned defaults and stage topology with the relevant pipeline.
- Protect current public/server behavior with an explicit schema parity audit before freezing the new surface.
- Preserve backward compatibility long enough to migrate examples, internal users, and servers safely.
## Non-Goals
- Do not make Ray a structural dependency or copy its package layout.
- Do not make a raw free-form dict the primary Python API.
- Do not force all models into one universal `RefineConfig`.
- Do not expose stage indices as the primary user interface.
- Do not move every shared config class into per-model directories.
## External Inspiration
### Ray
Borrow only the ergonomic idea that user-facing config can be expressed as a string-keyed dict or YAML/JSON config. Do not copy Ray's structure into FastVideo.
### SGL Multimodal Gen
Useful ideas: split instance config from request config; allow dict input at the boundary; parse dicts immediately into typed request objects; merge request overrides onto model defaults; validate request params against pipeline/task type. Do not copy: request objects depending on server/engine config; broad weakly typed request bags as the canonical API.
### vLLM-Omni
Useful ideas: model-owned pipeline presets; explicit stage topology; per-stage default sampling params; clean separation between stage topology, engine defaults, and runtime overrides. Do not copy: positional `sampling_params_list` as the primary public API; serving-engine-oriented stage index semantics in the main Python interface.
## Core Decision
FastVideo should have:
1. A shared typed public schema.
2. Model-owned named pipeline presets.
3. Semantic stage overrides by stage name.
4. Optional advanced explicit plans for power users.
5. YAML-first config loading with dotted CLI overrides.
The public API should be stable at the schema level, while model-specific behavior should be contained in preset definitions and model-specific typed override classes.
## Schema Parity Requirement
Before the new schema is declared canonical, FastVideo should build a parity inventory across all current public inference surfaces (Python `VideoGenerator` kwargs, CLI flags, YAML/JSON config inputs, OpenAI/server request models, model-specific sampling/runtime fields). Each field must be marked: kept as-is, renamed, moved to a nested path, preset-owned, private-only adapter field, or intentionally dropped. No field should disappear implicitly.
For any public field that remains supported, there should be either a normalized-config equivalence test, or an explicit parser/translation test. Fields that exist only in private Dreamverse integration code should be handled by a private adapter layer, not quietly converted into public FastVideo compatibility guarantees.
Landed artifact: [inference_schema_parity_inventory.yaml](docs/design/inference_schema_parity_inventory.yaml) + guard [test_schema_parity_inventory.py](fastvideo/tests/api/test_schema_parity_inventory.py).
## Canonical Public Schema
The typed schema is implemented in [fastvideo/api/schema.py](fastvideo/api/schema.py). Envelope types:
- `RunConfig` — offline: `generator` (GeneratorConfig) + `request` (GenerationRequest)
- `ServeConfig` — serving: `generator` + `server` (ServerConfig) + `default_request` (GenerationRequest) + optional `streaming` (StreamingConfig)
Key nested types (summary; full fields in `schema.py`):
- `GeneratorConfig` → `model_path`, `revision`, `trust_remote_code`, `engine` (EngineConfig: parallelism/offload/compile/quantization/flags), `pipeline` (PipelineSelection: workload_type, preset, preset_version, components, preset_overrides, experimental)
- `GenerationRequest` → `prompt`, `negative_prompt`, `inputs` (InputConfig), `sampling` (SamplingConfig), `runtime` (RequestRuntimeConfig), `output` (OutputConfig), `stage_overrides`, `state` (ContinuationState), `plan` (GenerationPlan), `extensions`
- `ContinuationState` → opaque `{kind: str, payload: dict[str, Any]}`
- `GenerationPlan` → `{stages: list[PlannedStage], final_stage: str | None}`; advanced/escape-hatch only
### Important Semantics
- Dataclasses are canonical for Python users.
- Dict and YAML/JSON are parsed into these dataclasses immediately.
- Unknown keys must raise validation errors.
- Typed `GenerationRequest` defaults come from the public schema, not from model-specific `SamplingParam.from_pretrained(...)` defaults.
- Legacy `generate_video(...)` continues to inherit model-specific sampling defaults until the SSIM/performance migration lands (PR 11).
- The only open-ended escape hatches are:
- `generator.pipeline.experimental`
- `request.extensions`
That keeps the public contract strict without blocking experimental work.
### Request Mutation Tracking
When a `GenerationRequest` is parsed from a raw dict (YAML, JSON, or Python mapping), FastVideo records which fields the user explicitly provided versus which received schema defaults. This matters because `request_to_sampling_param()` must distinguish user-provided values (which should override model defaults) from schema defaults (which should NOT override model defaults).
The tracking contract:
- At parse time, the original raw dict and a baseline snapshot of the parsed object are stored on the request.
- Dataclass field mutations after parsing (e.g., `request.sampling.seed = 7`) are captured via lightweight `__setattr__` dirty-path recording.
- Dict-typed field mutations (e.g., `del request.stage_overrides["refine"]`) are detected at access time by diffing the current dict against the baseline snapshot.
- Setting a field to the schema default value IS captured as explicit, so it will override model defaults.
- The raw dict is reconciled lazily when `normalize_generation_request()` is called, not on every individual mutation.
### Schema Purity and Model-Specific Fields
The shared schema currently contains fields that are specific to one or two model families. These remain for backward compatibility during the initial migration (PRs 0-3) but should migrate to preset-owned typed override classes as the preset system lands (PRs 4-10).
**SamplingConfig fields to migrate:**
- `height_sr`, `width_sr`, `num_inference_steps_sr`: Hunyuan15 SR only. Target: `HunyuanSRStageOverride` in PR 10.
- `guidance_scale_2`, `boundary_ratio`: Wan2.2 and LingBotWorld only. Target: preset-owned overrides in the relevant model migration PR.
**InputConfig fields to migrate:**
- `mouse_cond`, `keyboard_cond`, `grid_sizes`: MatrixGame action control only. Target: `request.extensions` or a typed MatrixGame input config.
- `c2ws_plucker_emb`: LingBotWorld camera control only. Target: `request.extensions` or a typed LingBotWorld input config.
- `refine_from`, `stage1_video`: LongCat refinement only. Target: `LongCatRefineStageOverride` inputs or keep in `InputConfig` if they remain a public contract.
**Universal fields that stay in the shared schema:**
- `guidance_rescale`: used by multiple denoising stages across models, default 0.0. Universally applicable.
- `true_cfg_scale`: OpenAI adapter surface. Keep for protocol compatibility.
### Escape Hatch Sunset
`generator.pipeline.experimental` and `request.extensions` are intentional escape hatches for experimental and private work. They bypass strict validation by design.
Rules for escape hatch usage:
- New fields should not be added to `experimental` or `extensions` without a plan to either promote them to typed fields or remove them within two PR cycles.
- Each model migration PR (PRs 6-10) should review and shrink escape hatch usage for that model family.
- The compatibility layer currently routes unrecognized legacy kwargs into `experimental`. This pass-through should shrink as presets absorb model-specific fields.
## Public Python API
### New Canonical API
```python
from fastvideo import VideoGenerator
from fastvideo.api import (
GeneratorConfig, GenerationRequest,
EngineConfig, OutputConfig,
PipelineSelection, SamplingConfig,
)
generator = VideoGenerator.from_pretrained(
config=GeneratorConfig(
model_path="/models/ltx2",
engine=EngineConfig(num_gpus=1),
pipeline=PipelineSelection(
workload_type="t2v",
preset="ltx2_two_stage",
),
)
)
result = generator.generate(
GenerationRequest(
prompt="a fox running through snow",
sampling=SamplingConfig(
num_frames=121, height=1024, width=1536,
num_inference_steps=8, seed=42,
),
output=OutputConfig(save_video=True, return_state=True),
)
)
```
### Accepted Construction Forms
Canonical:
```python
VideoGenerator.from_pretrained(config=GeneratorConfig(...))
VideoGenerator.from_config(GeneratorConfig(...))
VideoGenerator.from_file("run.yaml")
```
Stable convenience constructor:
```python
VideoGenerator.from_pretrained("model-id")
VideoGenerator.from_pretrained("model-id", num_gpus=2, use_fsdp_inference=False, ...)
```
Legacy compatibility:
```python
VideoGenerator.from_pretrained(model_path, **legacy_kwargs)
```
All constructor forms normalize through the same typed path. Stable convenience kwargs remain supported with no deprecation warning. Advanced model/pipeline-specific kwargs are accepted during migration but only as compatibility inputs that normalize into `GeneratorConfig`. The thing being deprecated over time is the unbounded legacy kwarg surface, not the `from_pretrained(...)` entrypoint itself.
### Generation Entry Point
Canonical: `generator.generate(request: GenerationRequest) -> GenerationResult`.
Compatibility alias: `generator.generate_video(prompt=..., **legacy_kwargs)` — converts legacy calls into a `GenerationRequest` and emits a deprecation warning.
During the compat period, `generate(request=...)` uses schema defaults while `generate_video(...)` preserves legacy model-default behavior. These paths intentionally differ until preset-owned defaults replace the remaining `SamplingParam` default logic (migrated in PR 11).
### Boundary Normalization Rule
Every public inference entrypoint normalizes into typed config objects before touching legacy internals. That includes Python constructors, generation calls, CLI `generate`, CLI `serve`, and OpenAI/server request translation. Legacy internals (`FastVideoArgs`, `SamplingParam`) may remain temporarily, but only behind a typed normalization boundary.
## Pipeline Presets
### Definition
An `InferencePreset` is a named model-owned preset that defines:
- workload selection
- stage topology
- per-stage defaults
- stage names
- allowed stage override types
- init-time feature requirements
The preset is not user-authored by default. It is supplied by the model integration.
### Why Presets Are The Right Abstraction
Users usually do not want to assemble a stage graph by hand. They want to say:
- use LongCat distill + refine
- use Hunyuan 1080p SR
- use LTX2 two-stage continuation mode
Presets provide a stable public noun for that behavior.
### Preset Naming Rules
- Use semantic names, not stage indices.
- Keep names stable across releases.
- If semantics change incompatibly, change `preset_version` or create a new preset name.
Examples: `ltx2_base`, `ltx2_two_stage`, `longcat_distill_refine`, `hunyuan15_sr_720p`, `hunyuan15_sr_1080p`.
### Preset-Owned Stage Names
Stage names are public and stable within a preset.
- LTX2: `base`, `refine`
- LongCat: `distill`, `refine`
- Hunyuan15: `base`, `sr_720p`, `sr_1080p`
Public overrides should reference these stage names, never stage indices.
## Stage Overrides
The main user override surface for multi-stage pipelines is:
```python
request.stage_overrides["refine"] = ...
```
Each model family should expose typed override classes for its stage names. Examples for the model families that land in PRs 6/9/10:
```python
@dataclass
class LTX2RefineStageOverride:
enabled: bool | None = None
num_inference_steps: int | None = None
guidance_scale: float | None = None
add_noise: bool | None = None
image_crf: int | None = None
video_position_offset_sec: float | None = None
@dataclass
class LongCatRefineStageOverride:
t_thresh: float | None = None
spatial_refine_only: bool | None = None
num_cond_frames: int | None = None
@dataclass
class HunyuanSRStageOverride:
num_inference_steps: int | None = None
guidance_scale: float | None = None
```
### Strictness Rules
- Stage names must exist in the selected preset.
- Override fields must be valid for that stage type.
- Unknown stage names and unknown fields must error.
## Advanced Explicit Plans
Presets should be the default API. `GenerationPlan` exists only for advanced composition or experimentation:
- building a custom workflow that is not yet standardized as a preset
- debugging or benchmarking stage combinations
- prototyping a future preset
Do not require `GenerationPlan` for normal users.
## Continuation State
Continuation must be a first-class part of the API.
### Public Contract
- `GenerationResult.state` may return a `ContinuationState`.
- `GenerationRequest.state` may accept a previously returned state.
- Most users should treat `state` as opaque and round-trip it back into the next request.
### Why This Matters
Dreamverse/LTX2 currently leaks continuation internals into app-level request fields like video conditions, audio clean latent, audio denoise mask, and segment offsets. Those should not remain top-level app-owned public API.
### State Design
Public surface:
```python
@dataclass
class ContinuationState:
kind: str
payload: dict[str, Any]
```
Internally, FastVideo should also define typed model-specific state subclasses, e.g. `LTX2ContinuationState` (PR 7) and `LongCatIntermediateState` if ever needed. Minimal stable surface: return state, pass state back in, validate that the state is compatible with the active preset.
Payload serialization: fields must be JSON-serializable or use an opaque blob-ID indirection for large tensors. This supports both the stateless OpenAI client round-trip AND future Dynamo prefill/decode disaggregation where prefill yields a state that decode hydrates across workers.
## YAML / JSON Design
YAML and JSON should be exact serializations of the typed schema, not a second unrelated config system. YAML is the primary documented format. JSON is accepted with the same schema.
### Run Config Example
```yaml
generator:
model_path: /models/ltx2
engine:
num_gpus: 1
parallelism: {tp_size: -1, sp_size: -1}
offload: {dit: false, text_encoder: false, vae: false, pin_cpu_memory: true}
pipeline:
workload_type: t2v
preset: ltx2_two_stage
components:
config_root: /models/ltx2-config
upsampler_weights: /models/ltx2-refine
lora_path: /models/ltx2-refine-lora
preset_overrides:
refine: {enabled: true, add_noise: true}
request:
prompt: "a fox running through snow"
sampling:
num_frames: 121
height: 1024
width: 1536
num_inference_steps: 8
seed: 42
output: {save_video: true, return_state: true}
stage_overrides:
refine: {num_inference_steps: 2, guidance_scale: 1.0}
```
### Serve Config Example
```yaml
generator:
model_path: /models/ltx2
engine: {num_gpus: 1}
pipeline: {workload_type: t2v, preset: ltx2_two_stage}
server: {host: 0.0.0.0, port: 8000, output_dir: outputs/}
default_request:
sampling: {num_frames: 121, height: 1024, width: 1536, num_inference_steps: 8}
output: {save_video: false, return_frames: false}
```
### Validation Rules
- top-level schema must match `RunConfig` or `ServeConfig`
- unknown keys must fail
- dotted CLI overrides are applied to the nested config before typed parsing
- parse errors must include the exact nested path that failed
## CLI Design
Inference CLI reuses the best parts of the current training authoring flow (YAML-first authoring, dotted nested overrides, typed parsing after merge) but stays stricter than training at the public boundary because it is a user-facing API surface for Python, CLI, YAML/JSON, and serving.
### Canonical CLI Forms
```bash
fastvideo generate --config run.yaml
fastvideo generate --config run.yaml --request.sampling.seed 42
fastvideo generate --config run.yaml --generator.engine.num_gpus 2
fastvideo serve --config serve.yaml
fastvideo serve --config serve.yaml --server.port 8090
```
The CLI is config-only. Beyond `--config`, CLI input uses dotted override paths into the nested schema rather than maintaining a second flat flag surface.
Implementation: YAML/JSON is loaded into a nested dict, dotted CLI overrides are applied to the nested dict, then the result is parsed into typed config objects. Flat CLI flags are rejected so the nested schema stays canonical.
## OpenAI / Server Mapping
`fastvideo serve` loads `ServeConfig`. Incoming HTTP requests are translated into `GenerationRequest` by:
1. cloning `default_request`
2. applying API request fields onto that request
3. validating against the selected preset
This is similar in spirit to the SGL pattern of merging user overrides onto model defaults.
Rules:
- HTTP request translation must not bypass typed validation.
- multi-stage defaults should come from the preset and `default_request`, not from ad hoc server-local logic.
- stateful continuation requests should accept and return typed `ContinuationState` payloads.
Landed in PR 5 for the stateless OpenAI server at `fastvideo/entrypoints/openai/`. The streaming/session server (PRs 7.5-7.9) uses the same preset/default_request merge through `ServeConfig.streaming`.
## Streaming Server + Dynamo Backend
The typed public API is consumed by three server-class integrations. They must share one execution substrate so we don't grow three near-duplicate progress loops.
### The three consumers
| Consumer | Transport | Request shape | State |
|---|---|---|---|
| Stateless OpenAI (`fastvideo/entrypoints/openai/`) | HTTP POST | `GenerationRequest` merged onto `ServeConfig.default_request` | Stateless; continuation via opaque payload if needed |
| Streaming WebSocket (`fastvideo/entrypoints/streaming/`) | WebSocket JSON + binary fMP4 | `GenerationRequest` per segment, session-scoped | Server-held session (per-GPU continuation cache); snapshot on demand |
| Dynamo native backend (`ai-dynamo/dynamo/components/src/dynamo/fastvideo/`) | Dynamo RPC endpoint | `NvCreateVideoRequest` ↔ adapter ↔ `GenerationRequest` | Aggregated today; disaggregated prefill/decode later via `ContinuationState` |
### Shared execution substrate: `VideoGenerator.generate_async`
The OpenAI server, streaming server, and Dynamo backend all want the same thing: a typed async API that yields progress events and a typed final result. FastVideo exposes exactly one canonical entry point:
```python
async def generate_async(
self,
request: GenerationRequest,
) -> AsyncGenerator[VideoEvent, None]: ...
```
Events:
```python
@dataclass
class VideoProgressEvent:
step: int
total_steps: int
stage: str # "denoise" | "refine" | "decode" | ...
@dataclass
class VideoPartialEvent:
frames: np.ndarray # shape: (num_frames, H, W, 3)
index: int # monotonic chunk index
@dataclass
class VideoFinalEvent:
video_bytes: bytes | None # mp4-encoded if requested
tensor: torch.Tensor | None # raw if requested
metadata: dict[str, Any]
continuation_state: ContinuationState | None
VideoEvent = VideoProgressEvent | VideoPartialEvent | VideoFinalEvent
```
The sync `generate_video(request=...) -> VideoResult` becomes a thin `asyncio.run` wrapper over `generate_async` that collects events and returns the final.
### Streaming server mapping
`fastvideo/entrypoints/streaming/` owns per-session state:
- `SessionStore.hydrate(state: ContinuationState) -> session_id`
- `SessionStore.snapshot(session_id) -> ContinuationState`
- Per-GPU implicit continuation cache (today's internal behavior) is wrapped as a `SessionStore` implementation.
Per-segment, the session writes a `GenerationRequest`, pipes the event stream to the WebSocket (progress → JSON messages, partial → fMP4 frames), and persists the final's `ContinuationState` into the session.
### Dynamo backend mapping
Dynamo's backend pattern (from `components/src/dynamo/sglang/`) is a pure Python import. FastVideo does not host a `fastvideo/entrypoints/dynamo/` subpackage; the integration lives in the Dynamo repo. FastVideo exposes a stable contract:
| Surface | Exposed as |
|---|---|
| Construction | `VideoGenerator.from_pretrained(model_path, **typed_kwargs)` |
| Execution (async) | `VideoGenerator.generate_async(request) -> AsyncGenerator[VideoEvent, None]` |
| Execution (sync) | `VideoGenerator.generate_video(request=...) -> VideoResult` |
| Typed request | `fastvideo.api.GenerationRequest`, `SamplingConfig`, `InputConfig` |
| Typed result | `fastvideo.api.VideoResult`, `VideoEvent`, `ContinuationState` |
| Health-check input | `VideoGenerator.default_health_check_request() -> GenerationRequest` |
| Config dump | `config_to_dict(cfg)` (already exists) |
Request/response mapping the Dynamo adapter must perform:
```
NvCreateVideoRequest -> fastvideo.api.GenerationRequest
prompt -> sampling.prompt
size="WxH" -> sampling.width, sampling.height
seconds -> seconds * nvext.fps -> sampling.num_frames
input_reference -> input.image_path | input.video_path
nvext.fps -> sampling.fps
nvext.num_frames -> sampling.num_frames (overrides seconds*fps)
nvext.num_inference_steps -> sampling.num_inference_steps
nvext.guidance_scale -> sampling.guidance_scale
nvext.seed -> sampling.seed
nvext.negative_prompt -> sampling.negative_prompt
response_format -> (handled at the adapter's output stage)
VideoFinalEvent -> NvVideosResponse
video_bytes -> data[0].b64_json (if response_format=b64_json)
uploaded URL -> data[0].url (if response_format=url)
metadata.inference_time_s -> inference_time_s
continuation_state -> (reserved for future disaggregation)
```
All fields already exist (or will exist after PR 6's typed-kwarg expansion) on FastVideo's typed schema. **The adapter lives entirely in the Dynamo repo** at `components/src/dynamo/fastvideo/` — FastVideo does not host any Dynamo subpackage, dep, or CLI. The only FastVideo obligation is the stable public Python API listed above.
### Constraints this places on other sections
- **Continuation State** (see earlier section): `ContinuationState.payload` must be JSON-serializable or use an opaque blob-ID indirection for large tensors. This supports both the stateless OpenAI client round-trip *and* future Dynamo prefill/decode disaggregation, where prefill yields a state that decode hydrates across workers.
- **Typed GeneratorConfig** (see Public Python API): every flat legacy LTX2 kwarg currently used by the internal `gpu_pool.py` must have a typed home reachable from `GeneratorConfig`. Dynamo's `FastVideoArgGroup` builds the config from its CLI and must not have to know any legacy LTX2 name.
- **Public exports**: `from fastvideo import VideoGenerator`; `from fastvideo.api import GenerationRequest, SamplingConfig, ContinuationState, VideoResult, VideoEvent, VideoProgressEvent, VideoPartialEvent, VideoFinalEvent`.
## Repo Layout
### Shared Public API
`fastvideo/api/` contains the shared public API package. Current files:
- `schema.py` — `RunConfig`, `ServeConfig`, `ServerConfig`, `GeneratorConfig`, and all nested typed config dataclasses
- `sampling_param.py` — `SamplingParam` + `CacheParams` (canonical home since PR 4; former `configs/sample/base.py` location removed)
- `presets.py` — `InferencePreset`, `PresetStageSpec`, registry APIs
- `results.py` — `GenerationResult` / `VideoResult`
- `parser.py` — `from_dict`, `to_dict`, `load_yaml`, `load_json`, validation
- `overrides.py` — dotted override application
- `compat.py` — legacy Python kwargs translation
- `errors.py` — path-aware validation errors
May split further by concern in a future cleanup.
### Pipeline-Local Model-Owned Config
Model-owned presets and override types live next to the model pipeline:
```text
fastvideo/pipelines/basic/ltx2/
ltx2_pipeline.py, presets.py, stage_overrides.py, continuation.py
fastvideo/pipelines/basic/longcat/
longcat_pipeline.py, presets.py, stage_overrides.py
fastvideo/pipelines/basic/hunyuan15/
hunyuan15_pipeline.py, hunyuan15_sr_pipeline.py, hunyuan15_2sr_pipeline.py,
presets.py, stage_overrides.py
```
PR 4 landed `presets.py` for all 13 model families. Remaining colocation targets are `pipeline_configs.py` (moving `configs/pipelines/<family>.py`) and model-specific stages (moving `pipelines/stages/<family>_*.py`); see [PR plan.md](PR%20plan.md) "Pipeline Package Structure".
### Registry
Central registry (`fastvideo/registry.py`) registers preset providers rather than owning all model-specific defaults directly. It answers:
- which pipeline class corresponds to a model path
- which presets are available for that model family
- which override/state classes are valid for a selected preset
## Relationship To Current Internal Classes
This refactor does not require deleting current internals immediately.
- `FastVideoArgs` is an internal compatibility/input adapter, no longer the primary public inference type.
- `SamplingParam` now lives in `fastvideo/api/sampling_param.py` and gets model-specific defaults from presets via `_from_preset()`. All 12 `SamplingParam` subclasses have been removed and the former `fastvideo/configs/sample/` directory has been deleted entirely (PR 4). It remains an internal adapter between the preset system and the runtime.
- current `PipelineConfig` classes can remain temporarily as internal component config carriers
- the new public schema is the stable boundary above them
`VideoGenerator` accepts the new schema and translates down into current execution internals. Legacy `generate_video(..., **kwargs)` stays on the direct execution path during the compat period until SSIM/performance tests migrate in PR 11.
## Model-Specific Design
### LTX2 / Dreamverse
LTX2 needs both:
- init-time two-stage feature wiring
- request-time continuation/refine behavior
Expressed as:
- preset: `ltx2_two_stage`
- init-time fields: refine assets, optional config root, stage enablement
- request-time fields: stage override for refine behavior, optional returned continuation state
#### LTX2 Preset Example
```yaml
generator:
pipeline:
preset: ltx2_two_stage
components:
config_root: /models/ltx2-config
upsampler_weights: /models/ltx2-refine
lora_path: /models/ltx2-refine-lora
preset_overrides:
refine: {enabled: true, add_noise: true}
```
#### LTX2 Request Example
```yaml
request:
prompt: "continue the previous sequence"
state: ${previous_result.state}
stage_overrides:
refine:
num_inference_steps: 2
guidance_scale: 1.0
image_crf: 18
output:
return_state: true
```
#### LTX2 Explicit Decisions
- `config_model_path` becomes `generator.pipeline.components.config_root`
- `ltx2_refine_*` stops being a pile of top-level kwargs
- continuation internals move into `ContinuationState`
- app-level code should pass `state`, not raw latent/audio condition payloads
### LongCat
LongCat should expose a named preset like `longcat_distill_refine` with stage topology `distill` and `refine`.
User-facing override knobs remain model-specific (`t_thresh`, `spatial_refine_only`, `num_cond_frames`) but live under:
```yaml
request:
stage_overrides:
refine:
t_thresh: 0.5
spatial_refine_only: false
num_cond_frames: 8
```
### Hunyuan 1.5 SR
Hunyuan already behaves like an integrated multi-stage pipeline. Expose it via presets: `hunyuan15_sr_720p`, `hunyuan15_sr_1080p`. Users should not need to know the exact internal pipeline class split between base and SR stages. Per-stage override surface should stay small and mostly sampling-focused.
Hunyuan15 presets (`hunyuan15_t2v_480p`, `hunyuan15_i2v_480p_distilled`, `hunyuan15_t2v_720p`, `hunyuan15_i2v_720p_distilled`, `hunyuan15_sr_1080p`) are implemented (PR 4). The `Hunyuan15_*_SamplingParam` subclasses have been removed; defaults (including precomputed sigmas) come from preset `defaults` dicts. Remaining work: adding typed `HunyuanSRStageOverride` classes and colocating PipelineConfig (PR 10).
## Exact Compatibility Mapping
Intended translation layer for common current fields.
| Legacy Field | New Path |
| --- | --- |
| `model_path` | `generator.model_path` |
| `revision` | `generator.revision` |
| `trust_remote_code` | `generator.trust_remote_code` |
| `workload_type` | `generator.pipeline.workload_type` |
| `num_gpus` | `generator.engine.num_gpus` |
| `tp_size` | `generator.engine.parallelism.tp_size` |
| `sp_size` | `generator.engine.parallelism.sp_size` |
| `dit_cpu_offload` | `generator.engine.offload.dit` |
| `dit_layerwise_offload` | `generator.engine.offload.dit_layerwise` |
| `text_encoder_cpu_offload` | `generator.engine.offload.text_encoder` |
| `image_encoder_cpu_offload` | `generator.engine.offload.image_encoder` |
| `vae_cpu_offload` | `generator.engine.offload.vae` |
| `pin_cpu_memory` | `generator.engine.offload.pin_cpu_memory` |
| `enable_torch_compile` | `generator.engine.compile.enabled` |
| `torch_compile_kwargs` | split across `generator.engine.compile.backend`, `.fullgraph`, `.mode`, `.dynamic`; uncommon keys land in `.extras` |
| `enable_torch_compile_text_encoder` | `generator.engine.compile.text_encoder_enabled` |
| `enable_stage_verification` | `generator.engine.enable_stage_verification` |
| `prompt_txt` | `request.inputs.prompt_path` |
| `prompt` | `request.prompt` |
| `negative_prompt` | `request.negative_prompt` |
| `image_path` | `request.inputs.image_path` |
| `video_path` | `request.inputs.video_path` |
| `output_path` | `request.output.output_path` |
| `output_video_name` | `request.output.output_video_name` |
| `save_video` | `request.output.save_video` |
| `return_frames` | `request.output.return_frames` |
| `num_videos_per_prompt` | `request.sampling.num_videos_per_prompt` |
| `seed` | `request.sampling.seed` |
| `num_frames` | `request.sampling.num_frames` |
| `height` | `request.sampling.height` |
| `width` | `request.sampling.width` |
| `fps` | `request.sampling.fps` |
| `num_inference_steps` | `request.sampling.num_inference_steps` |
| `guidance_scale` | `request.sampling.guidance_scale` |
| `guidance_scale_2` | `request.sampling.guidance_scale_2` |
| `guidance_rescale` | `request.sampling.guidance_rescale` |
| `true_cfg_scale` | `request.sampling.true_cfg_scale` |
| `boundary_ratio` | `request.sampling.boundary_ratio` |
| `sigmas` | `request.sampling.sigmas` |
| `enable_teacache` | `request.runtime.enable_teacache` |
| `return_trajectory_latents` | `request.runtime.return_trajectory_latents` |
| `return_trajectory_decoded` | `request.runtime.return_trajectory_decoded` |
### Private Dreamverse Adapter Mapping
The mappings below are useful for private Dreamverse migration, but they should not be treated as a public FastVideo backward-compatibility promise unless and until those fields actually exist in the public repo surfaces.
| Private Adapter Field | New Path |
| --- | --- |
| `config_model_path` | `generator.pipeline.components.config_root` |
| `ltx2_refine_enabled` | `generator.pipeline.preset_overrides.refine.enabled` |
| `ltx2_refine_upsampler_path` | `generator.pipeline.components.upsampler_weights` |
| `ltx2_refine_lora_path` | `generator.pipeline.components.lora_path` |
| `ltx2_refine_num_inference_steps` | `request.stage_overrides.refine.num_inference_steps` |
| `ltx2_refine_guidance_scale` | `request.stage_overrides.refine.guidance_scale` |
| `ltx2_refine_add_noise` | `generator.pipeline.preset_overrides.refine.add_noise` |
| `ltx2_image_crf` | `request.stage_overrides.refine.image_crf` |
| `return_continuation_state` | `request.output.return_state` |
### LongCat Legacy Mapping
| Legacy Field | New Path |
| --- | --- |
| `refine_from` | `request.inputs.refine_from` |
| `stage1_video` | `request.inputs.stage1_video` |
| `t_thresh` | `request.stage_overrides.refine.t_thresh` |
| `spatial_refine_only` | `request.stage_overrides.refine.spatial_refine_only` |
| `num_cond_frames` | `request.stage_overrides.refine.num_cond_frames` |
## Validation and Error Handling
### Strict by Default
All structured inputs should be strict by default: unknown keys error, wrong types error, invalid stage names error, incompatible state/preset combinations error.
### Exceptions
The only intentionally open-ended fields are `generator.pipeline.experimental` and `request.extensions`. These must be clearly documented as unstable and unsupported for long-term API compatibility.
### Error Quality
Validation errors should include the full nested path, expected type or valid choices, and preset/stage context when relevant:
```text
Invalid field: request.stage_overrides.refine.num_inference_steps
Expected int, got "two"
Preset: ltx2_two_stage
Stage: refine
```
## Implementation Plan
### Phases 0-5: Landed
- Phase 0 — Schema Parity Inventory: inventory complete; field classifications live in `docs/design/inference_schema_parity_inventory.yaml`; parity test guard in `fastvideo/tests/api/test_schema_parity_inventory.py`.
- Phase 1 — Shared Schema: `fastvideo/api/` with typed dataclasses, parser, validation, dotted overrides, `RunConfig`/`ServeConfig`.
- Phase 2 — VideoGenerator Compat: `from_config`, `from_file`, `generate(request=...)`, legacy `from_pretrained(..., **kwargs)` and `generate_video(..., **kwargs)` as compat shims routed through typed normalization.
- Phase 3 — CLI Refactor: `fastvideo generate` and `fastvideo serve` parse nested YAML/JSON with training-style dotted overrides; flat flag expansion removed as the canonical path.
- Phase 4 — Preset System: shared registry + pipeline-local `presets.py` for all 13 families; all 12 `SamplingParam` subclasses removed; `SamplingParam` moved to `fastvideo/api/sampling_param.py`.
- Phase 5 — Server Request Translation: `fastvideo serve` loads `ServeConfig`; stateless OpenAI endpoint clones `default_request` and merges validated user overrides.
### Remaining Phases
- **Phase 6 — LTX2 Public Upstream Path** (PR 6): upstream `ltx2_two_stage` preset; upstream continuation-state contract; upstream only repo-visible/public LTX2 surfaces into FastVideo.
- **Phase 7 — Dreamverse Adapter Migration** (PR 7 + private repo work): translate private Dreamverse-only request/config fields in a private adapter; replace raw app-owned continuation kwargs with `state` in the private server; do not expand the public FastVideo compatibility promise just to match private adapter fields.
- **Phase 7.5-7.10 — Streaming Server and Dynamo Contract** (PRs 7.5-7.10): upstream the streaming server (skeleton, GPU pool, prompt enhancer, auxiliaries, router) consuming `generate_async`; land the Dynamo backend contract (`VideoGenerator.generate_async`, health-check helper) with the Dynamo backend package itself living in the Dynamo repo.
- **Phase 8 — Model Migration and Docs** (PRs 9-10, 12): colocate `configs/pipelines/<family>.py` with pipeline implementations; add typed stage override classes for multi-stage models; update basic examples to the new API; document YAML-first inference config and migration guidance.
- **Phase 8.5 — Golden-Test Migration** (PR 11): keep SSIM/performance regression tests on legacy Python generation while preset defaults are still settling; one dedicated migration pass after the preset system and model-default behavior are stable; complete this migration before removing legacy Python inference entrypoints or kwargs.
- **Phase 9 — Deprecation and Cleanup** (PR 13): deprecate direct public use of `FastVideoArgs`; deprecate direct public use of `SamplingParam`; gradually reduce public documentation for flat flags; eventually remove legacy kwargs after downstream migration is complete.
## Final Recommendation
The public FastVideo inference API is being rebuilt around:
- typed nested configs
- model-owned named presets
- semantic stage overrides
- first-class continuation state
- YAML-first CLI with dotted overrides
The primary abstraction is `InferencePreset`, not raw kwargs and not a fully manual stage graph.
The repo is moving model-specific defaults closer to each pipeline, while keeping the public schema and parsing logic centralized.
Regression and quality tests follow the rollout. Unit/entrypoint tests migrated to the typed API early, but SSIM/performance suites only move once the typed path can express all current knobs without compatibility exceptions and produces stable defaults through presets (PR 11).
End state:
- stable Python typing
- clean YAML/JSON support
- a much better CLI story
- a sane path for Dreamverse/LTX2
- a unified abstraction for LongCat, Hunyuan, and future multi-stage models
@@ -1,285 +0,0 @@
# Dreamverse ↔ FastVideo Integration
## Status
Working integration record. Captures how Dreamverse consumes the
FastVideo public API today, what's already shared, what's still ad
hoc, and what migrations land alongside each PR in the API refactor
sequence.
Pinned versions (last reconciled this session):
| Repo | Branch | Commit | Note |
|---|---|---|---|
| FastVideo (public) | `origin/main` | `70ee5d23` | PR 6 merged |
| FastVideo (public) | `will/api_7` | `3de5f833` | PR 7 in flight (typed continuation state) |
| FastVideo-internal | `will/rebase-nbv` | `1adc513e` | pre-PR-1 on the API refactor; has live realtime runtime |
| Dreamverse | `master` | `dc500330` | uses local + remote FastVideo runtimes via `server/runtime/` |
## Related Documents
- [PR plan.md](../../PR%20plan.md) — PR-by-PR sequence for the API refactor
- [apirefactor.md](../../apirefactor.md) — design spec
- [streaming-server-upstream-plan.md](streaming-server-upstream-plan.md) — upstream plan for `ui/ltx2-streaming/server/`
- `../../../Dreamverse/server/video_generation.py` — Dreamverse's worker + local `ContinuationState`
- `../../../Dreamverse/server/runtime/{factory,backend,gpu_pool,interfaces}.py` — runtime abstraction
- `../../../FastVideo-internal/fastvideo/entrypoints/realtime/{api_server,local_runtime}.py` — internal's realtime runtime (PR 7.5/7.6 upstream source)
## Surface Area
Dreamverse depends on FastVideo across three surfaces. Listed in order
of how stable each is.
### 1. Pipeline construction (stable)
`Dreamverse/server/video_generation.py:VideoGenerationWorker` calls
`VideoGenerator.from_pretrained(...)` with flat LTX-2 kwargs today.
After PR 6 the typed `GeneratorConfig` path exists; Dreamverse can
migrate at its own pace.
| Dreamverse usage | FastVideo public surface (post-PR 6) |
|---|---|
| `VideoGenerator.from_pretrained(model_path, ltx2_refine_enabled=…, …)` | `VideoGenerator.from_pretrained(config=GeneratorConfig(...))` |
| Flat `torch_compile_kwargs={…}` dict | `engine.compile.{backend,fullgraph,mode,dynamic,extras}` |
| `ltx2_vae_tiling=True` | `pipeline.vae_tiling=True` |
| `ltx2_refine_*` family | `pipeline.preset_overrides.refine.*` + `pipeline.components.upsampler_weights` |
| `enable_torch_compile_text_encoder` | `engine.compile.text_encoder_enabled` |
The legacy flat-kwarg path stays supported via `compat.py`; migration
is opt-in. PR 13's deprecation warnings are the eventual nudge.
### 2. Realtime runtime (in flight: PRs 7.5–7.6)
`Dreamverse/server/runtime/factory.py` selects a runtime backend at
process start:
```python
def create_runtime_pool() -> RuntimePool:
if os.getenv("FASTVIDEO_REALTIME_BASE_URL"):
return FastVideoRealtimePool(base_url=..., ws_url=..., default_model_id=...)
return GPUPool(get_available_gpus()) # in-process, wraps fastvideo.entrypoints.realtime.local_runtime
```
Both backends speak the same `RuntimePool` / `RuntimeSlot` Protocol
(`server/runtime/interfaces.py`):
- `acquire(client_id, websocket=None) -> (gpu_id, RuntimeSlot)`
- `release(client_id)`
- `RuntimeSlot.{join_user, user_step, leave_user, register_stream_queue, …}`
Today both impls reach into FastVideo-internal's
`fastvideo.entrypoints.realtime.local_runtime` (which exposes
`RealtimeRuntimeConfig`, `GPUPool`, `GPUSlot`). The remote backend
talks HTTP+WS to a separately-deployed runtime of the same shape.
**Contract that PR 7.5/7.6 must preserve:**
- `RealtimeRuntimeConfig` accepts `model_registry`, `default_model_id`,
`default_height/width/num_frames/fps/num_inference_steps/guidance_scale/seed/negative_prompt`,
`default_ltx2_image_crf`, `startup_warmup_{enabled,prompt,timeout_seconds}`.
- `GPUPool(gpu_ids: list[int], config: RealtimeRuntimeConfig)` constructor.
- `pool.initialize() / shutdown() / acquire() / release() / get_status()`.
- HTTP endpoints on the remote variant: `GET /healthz`, `GET /readyz`,
`GET /status`, `WS /ws`. (These already match what
`Dreamverse/server/routes/health.py` consumes.)
When PR 7.6 lands the upstream of `fastvideo/entrypoints/realtime/`,
Dreamverse should not need any code change unless we rename the import
path. **Open: do we rename `realtime/` → `streaming/` to match the
public package introduced in PR 5.5?** A deprecation alias module
keeps both working during transition.
### 3. Continuation state (PR 7)
`Dreamverse/server/video_generation.py:89 ContinuationState` is
Dreamverse's hand-rolled per-session state holder. PR 7 introduces
the typed equivalent at `fastvideo/pipelines/basic/ltx2/continuation.py`.
#### Field mapping
| Dreamverse | PR 7 `LTX2ContinuationState` | Notes |
|---|---|---|
| `video_images: list[PIL.Image]` | `video_frames: list[np.ndarray]` (uint8 H×W×3) | numpy is leaner; Dreamverse already round-trips PIL→numpy→PIL just to add noise |
| `audio_latents: torch.Tensor` `[B, C, T, mel]` | `audio_latents: torch.Tensor` (safetensors-serialized; bf16-safe) | unchanged shape; safetensors preserves dtype incl. `bfloat16` |
| `LTX2_VIDEO_CONDITIONING_FRAME_IDX` (env) | `video_conditioning_frame_idx: int` | env constant → per-state field |
| `LTX2_VIDEO_CONDITIONING_STRENGTH` (env) | `video_conditioning_strength: float` | env constant → per-state field |
| `AUDIO_CONDITIONING_NUM_FRAMES` (env) | `audio_conditioning_num_frames: int` | env constant → per-state field |
| `AUDIO_CONDITIONING_STRENGTH` (env) | `audio_conditioning_strength: float` | env constant → per-state field |
| `audio_lps` (passed into `apply_audio`) | `audio_sample_rate: int \| None` | analogous; rename worth confirming with audio team |
| Computed `prefix_sec` per segment | `video_position_offset_sec: float` | **see open question below** |
| `segment_idx` (param to apply_*) | `segment_index: int` | per-state field |
| `VIDEO_CONTEXT_NOISE`, `AUDIO_CONTEXT_NOISE`, `ENABLE_AUDIO_COND` | not on state | runtime policy / regularization knobs, not portable session data |
| `apply_video / apply_audio / save_video / save_audio_latents / clear` | not on PR-7 state class | state is a pure data carrier; runtime owns lifecycle policy |
PR-7 is a strict superset of Dreamverse's data model **plus** lifts
several env globals into per-session typed fields.
#### Lifecycle mapping
| Dreamverse pattern | `SessionStore` API |
|---|---|
| `self.continuation = ContinuationState()` per session | `state = session_store.snapshot(sid) or LTX2ContinuationState()` |
| `apply_video(req_kwargs, segment_idx)` + `apply_audio(req_kwargs, segment_idx, audio_lps)` | `state = session_store.snapshot(sid)`; runtime builds request from `state.video_frames` / `state.audio_latents` etc. |
| `save_video(frames)` + `save_audio_latents(latents)` | runtime constructs new `LTX2ContinuationState`, then `session_store.store(sid, new_state.to_continuation_state())` |
| `clear()` at end of session | `session_store.drop(sid)` |
`SessionStore` and `BlobStore` ABCs ship with thread-safe in-memory
defaults (`InMemorySessionStore`, `InMemoryBlobStore`). Dreamverse can
adopt them as-is for the local runtime; remote runtimes can plug in
redis-backed implementations later.
#### Wire format (HTTP/WS round-trip)
Dreamverse's `FastVideoRealtimePool` already speaks the realtime
runtime's HTTP+WS protocol. When PR 7.5/7.6 land state emission on
the server side, the on-the-wire payload is the public envelope:
```json
{
"kind": "ltx2.v1",
"payload": {
"schema_version": 1,
"segment_index": 3,
"video_conditioning_frame_idx": 9,
"video_conditioning_strength": 0.75,
"audio_sample_rate": 24000,
"audio_conditioning_num_frames": 5,
"audio_conditioning_strength": 0.5,
"video_position_offset_sec": 0.2,
"video": {"frames_b64": ["..."]},
"audio": {"safetensors_b64": "..."},
"metadata": {}
}
}
```
JSON-serializable end-to-end; safetensors blob preserves audio dtype
(incl. bf16). For payloads above the inline threshold a `BlobStore`
indirection replaces the b64-encoded body with `{"blob_id": "..."}`;
the blob itself stays inside the runtime that produced it.
## Migration Plan
Per PR landed, Dreamverse adoption is opt-in.
### After PR 7 merges
Single-file change in Dreamverse, ~50-line PR:
1. Replace `server/video_generation.py:89 ContinuationState` import
with `from fastvideo.pipelines.basic.ltx2.continuation import LTX2ContinuationState`.
2. Move `apply_video`, `apply_audio`, `save_video`, `save_audio_latents`,
`clear` off the state class onto `VideoGenerationWorker` (these are
runtime policy that uses the state, not part of the state itself).
3. Update `apply_audio` to read knobs from `state.audio_conditioning_num_frames`
and `state.audio_conditioning_strength` instead of the env globals
`AUDIO_CONDITIONING_NUM_FRAMES` / `AUDIO_CONDITIONING_STRENGTH`. The
env globals can stay as defaults that populate the state when a new
session starts.
4. Same treatment for video knobs: `state.video_conditioning_frame_idx`,
`state.video_conditioning_strength`.
5. Frame storage swaps `list[PIL.Image]` for `list[np.ndarray]` —
simpler `save_video` (no PIL conversion) and simpler `clear` (no
`.close()` loop).
### After PR 7.5 lands streaming server skeleton
Dreamverse's runtime/factory.py either:
- Continues to construct `GPUPool` from `RealtimeRuntimeConfig` (the
current path), now backed by the upstreamed `fastvideo/entrypoints/realtime/`.
- Or migrates to the upstream's `ServeConfig.streaming` shape and
invokes `fastvideo serve --config realtime.yaml` as the launch path.
Either way, `Dreamverse/server/runtime/interfaces.py` `RuntimePool` /
`RuntimeSlot` Protocol can stay in place — it was modeled after the
realtime runtime's surface. No interface change needed.
### After PR 7.6 lands the GPU pool upstream
- The `local_runtime.py` import in
`Dreamverse/server/runtime/gpu_pool.py:24` becomes a public import
with the same symbols (`RealtimeRuntimeConfig`, `GPUPool`,
`get_available_gpus`).
- Per-GPU continuation state inside the worker (`ltx2_continuation_images`,
`ltx2_continuation_audio_latents`) gets replaced by a `SessionStore`
reference. Dreamverse doesn't see this change — it's runtime-internal.
- `request.state` / `result.state` round-trip starts working end-to-end
on the local runtime. Dreamverse's worker can begin reading
`result.state` and feeding `request.state` between segments.
### After PR 7.10 lands the Dynamo backend contract
- `VideoGenerator.generate_async(...) -> AsyncGenerator[VideoEvent, None]`
is the canonical API.
- Dreamverse's per-segment `user_step` flow can migrate from the legacy
sync `generate_video(..., **kwargs)` path to consuming the typed
event stream. Optional; the sync wrapper stays.
## Open Questions
### `video_position_offset_sec` semantics
Dreamverse computes `prefix_sec = float(audio_extra) / 24.0` per
segment in `apply_audio`. Not persisted on `ContinuationState`.
PR-7 has `video_position_offset_sec` as a **state field**. Two valid
interpretations:
(a) **Persistent across segments** — accumulating time offset for
long sessions; useful for time-coherent audio chaining.
(b) **Per-segment hint that rides on the carrier** — runtime
overwrites every time; field is harmless redundancy.
Field's docstring leans toward (b). Decide before PR 7.6 starts
emitting/consuming it. If we land on (a), document the accumulation
rule explicitly.
### `BlobStore` / `SessionStore` lifecycle ownership
PR 7's in-memory implementations have no eviction, no TTL, no
automatic blob cleanup on state replacement. Documented as a
per-deployment policy decision.
When PR 7.5/7.6 land the live consumer, who owns:
- bounded session capacity (LRU? TTL? hard max?)
- blob `drop()` chained when a state is replaced
- session expiry on websocket disconnect
Probably the streaming server's session manager, but worth stating
explicitly in PR 7.5's design.
### `realtime/` vs `streaming/` package naming
Currently:
- Public PR 5.5 introduced `fastvideo/entrypoints/streaming/` (skeleton + typed config).
- Internal has `fastvideo/entrypoints/realtime/` (live runtime).
- Dreamverse imports from `fastvideo.entrypoints.realtime` (per the internal name).
PR 7.5 either picks one or ships a deprecation alias module.
Recommendation in `streaming-server-upstream-plan.md`: keep
`streaming/` (it's the post-PR-5.5 public name), provide
`realtime/__init__.py` as a re-export with a `DeprecationWarning` for
one release cycle so internal/Dreamverse can land import updates.
## Test Coverage on the FastVideo Side
PR 7 ships:
- `fastvideo/tests/api/test_ltx2_continuation.py` — typed
state round-trip (inline + blob), bf16 preservation, JSON
serializability, kind/version validation, schema_version guard.
- `fastvideo/tests/entrypoints/streaming/test_session_store.py` —
store/snapshot/hydrate/drop behavior on `InMemorySessionStore`;
put/get/drop on `InMemoryBlobStore`; thread-safety of both.
PR 7.5+ should add a contract test that exercises the round-trip via
the same wire format Dreamverse's `FastVideoRealtimePool` consumes.
## Changelog
| Date | Change |
|------|--------|
| 2026-04-23 | Initial draft. Captures PR 6 / PR 7 mapping; open questions on `video_position_offset_sec`, lifecycle ownership, and `realtime/` vs `streaming/` naming. |
@@ -1,390 +0,0 @@
# Dreamverse Integration Review Log
This document tracks design decisions, open questions, and integration-time
choices made while landing the public-side stacked PRs (7.7 → 8) and switching
Dreamverse from `FastVideo-internal` to public `FastVideo`. The user will
review this carefully — entries are deliberately verbose about *why*.
## Goal
Replace Dreamverse's dependency on `FastVideo-internal` with the public
`FastVideo` package, using the upstreamed streaming server stack
(`fastvideo.entrypoints.streaming.*`) where Dreamverse currently has local
copies or imports private modules.
## Surfaces Dreamverse currently uses from FastVideo-internal
(from `/home/william5lin/Dreamverse/server/`, scanned 2026-04-26):
| Dreamverse import | Internal path | Public replacement |
|---|---|---|
| `fastvideo.entrypoints.realtime.local_runtime.RealtimeRuntimeConfig` | `FastVideo-internal/fastvideo/entrypoints/realtime/local_runtime.py` | (none) — Dreamverse rewires through `streaming.gpu_pool.SubprocessGpuPool` |
| `fastvideo.entrypoints.realtime.local_runtime.GPUPool` | same as above | `fastvideo.entrypoints.streaming.gpu_pool.SubprocessGpuPool` (PR 7.6) |
| `fastvideo.configs.pipelines.base.PipelineConfig` | already in public | unchanged |
| `fastvideo.entrypoints.video_generator.VideoGenerator` | already in public | unchanged |
| `fastvideo.layers.quantization.fp4_config.FP4Config` | already in public | unchanged |
| `fastvideo.utils.maybe_download_model` | already in public | unchanged |
| `fastvideo.models.audio.ltx2_audio_processing.AudioProcessor` | already in public | unchanged |
| `fastvideo.models.loader.component_loader.ComponentLoader` | already in public | unchanged |
| `fastvideo.models.dits.ltx2.*` | already in public | unchanged |
| local copy: `Dreamverse/server/prompt_enhancer.py` (1933 lines) | mirrors `FastVideo-internal/.../prompt_enhancer.py` | `fastvideo.entrypoints.streaming.prompt.*` (PR 7.7) |
| local copy: `Dreamverse/server/prompt_safety.py` | mirrors `FastVideo-internal/.../prompt_safety.py` | `fastvideo.entrypoints.streaming.prompt.safety` (PR 7.8) |
| local copy: `Dreamverse/server/session_logger.py` | mirrors `FastVideo-internal/.../session_logger.py` | `fastvideo.entrypoints.streaming.session_logger` (PR 7.8) |
| local copy: `Dreamverse/server/rewrite_prompt_payload.py` | mirrors `FastVideo-internal/.../rewrite_prompt_payload.py` | `fastvideo.entrypoints.streaming.prompt.rewrite` (PR 7.8) |
| local copy: `Dreamverse/server/mock_server.py` (1200 lines) | mirrors `FastVideo-internal/.../mock_server.py` | `fastvideo.entrypoints.streaming.mock_server` (PR 7.8) |
| local copy: `Dreamverse/server/session_init_image.py` | mirrors `FastVideo-internal/.../session_init_image.py` | `fastvideo.entrypoints.streaming.session_init_image` (PR 7.5 — already public) |
## Design decisions made (auto-resolved)
### D-1: Realtime runtime → streaming GpuPool migration shape
**Context.** Dreamverse's `server/runtime/gpu_pool.py` thin-wraps
`fastvideo.entrypoints.realtime.local_runtime.GPUPool`, which takes a
`RealtimeRuntimeConfig(model_registry=…, default_model_id=…, default_height=…,
default_width=…, default_num_frames=…, default_num_inference_steps=…,
startup_warmup_*…)`. The public `streaming.gpu_pool.SubprocessGpuPool` takes a
typed `GeneratorConfig` + `GpuPoolConfig` + `WarmupConfig`.
The shapes differ in two important ways:
1. The internal version had a multi-model registry (`model_id → model_config`
dict). The public version is single-model (one `GeneratorConfig`).
2. The internal version flattened a few sampling defaults (height/width/frames/
steps) into the runtime config. The public version expects them as part of
the per-request `SamplingConfig`.
**Decision.** Dreamverse will:
1. Drop the multi-model registry on the integration branch (it is not used in
production today — Dreamverse boots one model per replica).
2. Construct a `GeneratorConfig` for the chosen model from `MODEL_REGISTRY[id]`
and pass it to `SubprocessGpuPool`.
3. Move the `default_height` / `default_width` / `default_num_frames` /
`default_num_inference_steps` defaults into a server-side
`default_request: GenerationRequest` template the session controller fills
from per-request input.
**Why.** Multi-model is feasible to add back later (one pool per model id,
acquire by `(session_id, model_id)`), but not on the migration branch — that
would couple the upstream switch to a feature redesign. Punting keeps the
upstream switch a pure mechanical refactor.
**Risk.** If a Dreamverse code path silently relied on the registry to swap
models per-session, the migration branch will surface that as a missing-model
error. The integration tests must exercise at least one segment per supported
model id before merging the Dreamverse branch.
### D-2: PR 7.7 prompt enhancer API surface narrower than the internal one
**Context.** The upstreamed `PromptEnhancer.enhance/auto_extend/rewrite` returns
`LLMResponse(content, provider, model, latency_ms, fallback_used)`. The internal
`enhance_prompt` / `generate_auto_prompt` / `rewrite_prompt_sequence` returns
`EnhanceResult(prompt, fallback_used, error, provider, model, latency_ms)` /
`RewriteResult(prompts, …, rollout_id, rollout_label, raw_response_text)`.
**Decision.** The Dreamverse integration branch will adapt at the call site:
- `enhancer.enhance_prompt(...)` → `enhancer.enhance(prompt)` + a thin shim
that maps the structured response into the existing `EnhanceResult` shape
for the session-controller code path. Move the shim to
`Dreamverse/server/prompting/_internal_compat.py`.
- The locked-segment / next-segment-index plumbing the internal version
built into the user payload becomes Dreamverse-side template logic in
the shim.
- The JSON-shaped responses the internal prompts assume (`{"next_prompt":
"..."}` / `{"segment_prompts": [...]}`) become Dreamverse-side
parsing in the shim, since the public `LLMResponse` is intentionally raw.
**Why.** The public surface stays minimal and provider-agnostic; the
LTX-2-specific orchestration (locked segments, rollout id/label, JSON
schemas) is an internal-UI concern, not something every public consumer
should wear. Dreamverse keeps its existing call shape; the public stays
clean.
**Open question for review:** Should we promote some of this into
`fastvideo.entrypoints.streaming.prompt.ltx2_orchestration` (or similar)
once a second consumer appears? Logging here so we have the option.
### D-3: Multi-stage provider race (Dreamverse) vs sequential fallback (public)
**Context.** The internal enhancer runs all providers in a stage in parallel
and returns the first to succeed (`_run_provider_race`). The public
enhancer runs providers strictly sequentially with retryable-error fallback.
**Decision.** Public stays sequential for PR 7.7. The race-based fallback is
a Dreamverse-specific tail-latency optimization that depends on parallel API
budgets; promoting it would force every public consumer to have multiple
provider keys configured. Dreamverse can keep `_run_provider_race` as an
internal optimization on its side.
**Risk.** First-segment latency on Dreamverse may regress slightly when
Cerebras is having a bad minute (sequential fallback waits the full
20s timeout before trying Groq). If this is a real production concern,
add a public knob like `concurrency: int = 1` on `PromptEnhancer` that
gates a race path — but only after measuring.
### D-4: Skipping PR 7.9 router for the integration branch
**Context.** The internal stack ships a `router/main.py` that load-balances
across replicas with health checks. Dreamverse's deployment uses a single
replica per region (per `gpu_pool.py:_parse_requested_gpu_limit`).
**Decision.** Land PR 7.9 on the public side (so the surface is upstreamed)
but skip wiring it into the Dreamverse integration branch. Dreamverse's
`server/main.py` does not import from `router/`.
### D-5: Audio re-encode (PR 7.10) needed for streaming, deferred
**Context.** The internal streaming server's per-step path runs an audio
re-encode (`_re_encode_audio` inside `_stream_av_fmp4_events` /
`do_step_ltx2`) so each fMP4 segment ships with continuation-conditioning
audio. The whole-segment `pool.run()` path the public streaming server
currently uses doesn't need this. The PR plan defers re-encode integration
to PR 7.10 (`generate_async` / per-step streaming).
**Decision.** Land PR 7.10's `generate_async` on the public side. The
Dreamverse integration branch initially keeps using `pool.run()` (whole
segment, no re-encode); a follow-up branch swaps it to
`generate_async` + audio re-encode once that path is exercised end-to-end.
### D-6: `realtime/local_runtime.py` is *not* upstreamed
**Context.** It is the FastVideo-internal precursor to `streaming.gpu_pool`.
Upstreaming both would create two GPU pool implementations in the public
repo.
**Decision.** Don't upstream `realtime/local_runtime.py`. Dreamverse switches
to `streaming.gpu_pool.SubprocessGpuPool` on the integration branch. The
internal module can be deleted from FastVideo-internal at a follow-up.
## Open questions for user review
Each section below is a place the auto-decision could plausibly be wrong.
Please flip / annotate these in review.
### Q-1 Multi-model GPU pool (D-1)
Does any current Dreamverse production flow load multiple model ids
concurrently? If yes, we need to either (a) keep `realtime/local_runtime`
alive on the internal side until the public side gains a multi-model pool,
or (b) build the multi-model abstraction upstream as part of PR 7.6 follow-up
work.
### Q-2 Promoting LTX-2 prompt orchestration (D-2)
The locked-segments / next-segment-index / JSON-response orchestration is
LTX-2-specific. If Cosmos / Wan / Hunyuan ever grow a similar continuation
flow, we'll regret keeping the orchestration on the consumer side. Worth
promoting now?
### Q-3 Race-based provider fallback (D-3)
The sequential fallback in the public enhancer adds up to `timeout_ms` of
extra latency per failing provider before the next is tried. For Dreamverse
that's 20s. Should we land the race path now behind a `concurrency: int = 1`
knob, or wait until we have data?
### Q-4 Router upstream skip on Dreamverse branch (D-4)
We're upstreaming PR 7.9 (router) but not consuming it in the Dreamverse
integration branch. Is that right? Dreamverse currently has no router
component, so the answer is probably yes — but flagging.
### Q-5 generate_async cutover for the streaming path (D-5)
The plan leaves Dreamverse using `pool.run` (whole segment) initially.
Audio re-encode for cross-segment continuity is deferred to a follow-up.
Is that acceptable for the first switch, or does Dreamverse audio quality
regress relative to the internal path until 7.10 is wired in?
## PR-by-PR execution log
### PR 7.6 — already opened (#1257)
`will/api_7.6` rebased onto `origin/main`, with subprocess-pool robustness
review fixes pushed (boot_ok event, dead-worker detection, parallel shutdown,
reader-exit pending-job cleanup). 17/17 gpu_pool tests + 89/89 streaming
tests green at head.
### PR 7.7 — already opened (#1258)
`will/api_7.7` rebased onto the new 7.6 + LLM provider review fixes applied
locally (per-instance `retryable`, 4xx-non-retryable, json-decode wrap,
shared `_openai_compat.complete_openai_compatible`, `dataclasses.replace`
for the fallback marker). 29/29 prompt tests + 120/120 streaming tests green.
**Pending push** — the user opted to push this branch themselves.
### PR 7.8 — rebased onto new 7.7
`will/api_7.8` two commits replayed cleanly on the new 7.7. Adds
`fastvideo/entrypoints/streaming/{prompt/safety,prompt/rewrite,session_logger,
mock_server}.py` plus `test_auxiliaries.py`. 141/141 streaming tests green.
Notable gap vs internal version: the public `PromptSafetyFilter` ships one
classifier slot (`unsafe` label, single threshold) whereas the internal
version chained an NSFW filter and a hate-speech filter with marker-based
label matching. Multi-classifier composition is left to Dreamverse —
operators chain two filters explicitly. See **D-7** below.
### PR 7.9 — rebased onto new 7.8
`will/api_7.9` three commits replayed cleanly. Adds streaming router
(`router/{config,registry,main}.py`), `fastvideo router-serve` CLI
subcommand, and `test_router.py`. 151/151 streaming tests green.
Caveat: router/main.py uses the deprecated FastAPI `app.on_event("shutdown")`
hook — emits a DeprecationWarning. Migration to lifespan handlers is a
pre-merge cleanup item but not a blocker.
### PR 7.10 — rebased onto new 7.9
`will/api_7.10` three commits replayed with two trivial conflicts (line
wrap in `server.py`, redundant test in `test_cli_translation.py`). Adds
`VideoEvent` hierarchy, `VideoGenerator.generate_async`,
`default_health_check_request`, plus `test_generate_async.py` (273-line
contract test). 184/184 streaming + contract tests green.
### PR 8 — rebased onto new 7.10
`will/api_8` four commits → three (the 4th was a duplicate
`streaming.md` doc that 7.5 already shipped, dropped during rebase).
Adds `docs/design/server_contracts/{dynamo,index,openai}.md`,
`mkdocs.yml` entries, and `fastvideo/tests/contract/test_{dreamverse,
dynamo}_shape.py`. 206/206 streaming + contract tests green.
### Dreamverse `will/integrate-public-fastvideo`
Branch created from Dreamverse `master`. Single change: `pyproject.toml`
swaps `fastvideo = { path = "../FastVideo-internal", editable = true }`
to point at `../FastVideo`. Comment added linking back to this review
doc.
**Verified:** every TRACKED `from fastvideo.*` import in Dreamverse
(`server/video_generation.py` only) resolves against the public
package — except `fastvideo.layers.quantization.fp4_config.FP4Config`
(see **D-7** / Q-6 below).
**Untracked WIP** in `Dreamverse/server/{config,prompting,runtime,session}/`
imports `fastvideo.entrypoints.realtime.local_runtime` (D-6); this
branch does not migrate that WIP. The user's existing untracked work
stays untouched and will need a separate follow-up to consume
`streaming.gpu_pool.SubprocessGpuPool`.
## Test ladder (built-up to e2e per user request)
Each rung verifies the integration switch at one layer. Run from the
narrowest to the broadest before running the full e2e against real
GPU + model weights.
| # | Layer | Command | Status against the switched stack |
|---|---|---|---|
| 1 | Public FastVideo unit + contract tests | `pytest fastvideo/tests/api/ fastvideo/tests/entrypoints/streaming/ fastvideo/tests/contract/` | 358/358 passing on `will/api_8` |
| 2 | Public FastVideo FP4 lazy-import | `pytest fastvideo/tests/ops/quantization/test_fp4_config.py` | 3/3 passing |
| 3 | Dreamverse Python tests | `cd Dreamverse && uv run pytest server/tests/ -k "not stress and not benchmark and not health_endpoint"` | 73/73 passing against public FastVideo |
| 4 | Dreamverse FE unit/integration (vitest) | `cd Dreamverse/apps/web && npm test` | 54/86 passing — 32 failures are pre-existing copy-mismatches in `reducer.test.ts` etc., not caused by the switch |
| 5 | Backend HTTP smoke (Playwright) | `cd Dreamverse/apps/web && PLAYWRIGHT_SKIP_WEBSERVER=1 PLAYWRIGHT_BASE_URL=http://127.0.0.1:8009 npx playwright test e2e/backend-health.spec.ts` | 4/4 passing (5th correctly skipped because devtools-only route is off) |
| 6 | Frontend shell smoke (Playwright) | `npx playwright test e2e/frontend-shell.spec.ts` | Pending — requires Next.js dev server to be reachable; was stuck during this run, needs a clean restart |
| 7 | Full e2e preset generation | `npx playwright test e2e/preset-prompt-generation.spec.ts` | **8/8 passing** end-to-end after restart with `CUDA_VISIBLE_DEVICES=4 ENABLE_TORCH_COMPILE=0 FASTVIDEO_GPU_COUNT=1 FASTVIDEO_ENABLE_DEVTOOLS=1`. BE warmup + GPU 4 idle slot let `/readyz` flip green; the spec verifies preset → WS → backend handshake → "Generating video…" state. |
### How to reproduce e2e tier 7 from cold
```
# 1. BE — picks an idle GPU and skips torch.compile (avoids the
# aarch64 cross-compiler bug in the conda env's triton stack).
cd ~/Dreamverse
set -a; source ~/.env; set +a
CUDA_VISIBLE_DEVICES=4 ENABLE_TORCH_COMPILE=0 \
FASTVIDEO_ENABLE_DEVTOOLS=1 FASTVIDEO_GPU_COUNT=1 \
uv run dreamverse-server &
# 2. Wait for /readyz (~2 min for warmup x2 segments)
until curl -fsS http://127.0.0.1:8009/readyz >/dev/null; do sleep 5; done
# 3. FE
cd ~/Dreamverse/apps/web
BACKEND_URL=http://127.0.0.1:8009 NEXT_PUBLIC_INCLUDE_DEVTOOLS=1 \
npm run dev:devtools &
# 4. Playwright
cd ~/Dreamverse/apps/web
PLAYWRIGHT_SKIP_WEBSERVER=1 \
PLAYWRIGHT_BASE_URL=http://127.0.0.1:5274 \
BACKEND_URL=http://127.0.0.1:8009 \
npx playwright test --project=chromium --reporter=list
```
### Surfaced during the e2e debug pass (logged here for follow-up)
* **`SamplingParam has no field ltx2_image_crf`** — Dreamverse's
`server/video_generation.py:406` passes `ltx2_image_crf=0.0` to a
`SamplingParam(...)` constructor. The internal SamplingParam (in
`fastvideo/configs/sample/base.py`) declared this field; the public
`fastvideo.api.sampling_param.SamplingParam` does not. Currently
the BE logs an `ERROR` and silently drops the kwarg; warmup still
succeeds because the field is non-load-bearing for FP4-disabled
inference. Either re-add the field to the public schema or update
Dreamverse to stop passing it. **D-8.**
* **`aarch64-conda-linux-gnu-cc` triton compile failure** — the conda
env we boot from injects an ARM cross-compiler ahead of `gcc` on
`$PATH`, so `torch._inductor`'s triton launcher fails compilation.
Setting `ENABLE_TORCH_COMPILE=0` bypasses it. Long-term fix: clean
the conda env's compiler shadowing or add a `CC=gcc` override in
Dreamverse's worker bootstrap. **D-9.**
* **GPU pool starts but warmup OOMs on a shared GPU** — when
`CUDA_VISIBLE_DEVICES` lands on a GPU another tenant is using
(107 GiB-pegged training run on GPU 0 in this case), LTX-2 warmup
fails with OOM. Picking an idle GPU (4-7 here) is a manual step.
A pre-warm probe that checks free memory before booting the pool
would prevent this. **D-10.**
* **ffmpeg fragment write `Broken pipe`** — when the WS client closes
before the backend finishes streaming the first segment, ffmpeg
hits `[Errno 32] Broken pipe`. Currently Dreamverse's
`gpu_pool.handle_command` re-raises this as a session error,
which then propagates to "User step failed". Cosmetic for now —
swallowing pipe-broken on intentional disconnect would clean up
the logs. **D-11.**
## Additional integration gaps surfaced during the switch
### D-7: `FP4Config` is private-only
**Context.** `Dreamverse/server/video_generation.py:271` imports
`fastvideo.layers.quantization.fp4_config.FP4Config` and assigns it to
`pipeline_config.dit_config.quant_config`. The 411-line module lives only
in `FastVideo-internal/fastvideo/layers/quantization/fp4_config.py` and
hard-imports `flashinfer` at module top — it never made the public
upstream pass. Public has `base_config.py` and `absmax_fp8.py` only.
**Decision (provisional).** Don't upstream `fp4_config.py` in this
session. Reasons:
1. It introduces a new external dependency (`flashinfer`) the public
package has avoided so far.
2. The class hard-codes LTX-2 layer paths
(`ltx2.blocks.{i}.attn1.to_q` etc.) — this is "LTX-2-specific FP4",
not generic FP4. Belongs colocated with `pipelines/basic/ltx2/` if
it goes anywhere.
3. The FP4 pre-quantize/forward op surface is the kind of thing where
a careful review pass matters more than a bulk copy.
**What this means for the integration branch.** Dreamverse will boot
fine; only the FP4-quantized path inside `video_generation.py:283`
will fail (lazy import). For workflows that don't enable FP4
quantization, the integration is complete.
### Q-6 (review): how to land FP4Config publicly?
Two reasonable next steps:
1. **Colocate.** Move FP4 code to `fastvideo/pipelines/basic/ltx2/quantization.py`
with `flashinfer` as an optional extra: `pip install fastvideo[fp4]`.
Refactor `FP4QuantizeMethod` to take its layer-prefix list from a
pipeline-config field instead of hardcoding ltx2 paths so the
approach generalizes.
2. **Keep private.** Treat FP4 as a Dreamverse-side concern — Dreamverse
imports `fp4_config` from the internal repo via a thin shim. Public
FastVideo stays focused on generic surfaces. This means the
"FastVideo-internal removable" goal is partially undone.
Recommendation: option 1 once the API refactor settles — wait until
the LTX-2 colocation step (PR 9 / 10 territory) and land FP4 there.
@@ -1,518 +0,0 @@
# Handoff: LTX-2 NVFP4 wire-up + Dreamverse launch-demo skill
This document hands off in-flight work to the next coding agent. It covers
two related streams that landed across two repos:
1. **FastVideo** (`will/ltx2_sr_port`): wire NVFP4 (NVIDIA's block-scaled
FP4) inference + per-component torch.compile + supporting parity fixes
so the public package matches `FastVideo-internal` for the LTX-2
distilled streaming path used by Dreamverse.
2. **Dreamverse** (`will/integrate-public-fastvideo`): switch the GPU
worker to the typed `GeneratorConfig` API, rename `FP4Config` →
`NVFP4Config`, add a `launch-demo` skill + canonical
`serve_configs/streaming_demo.yaml` for `fastvideo serve --config`.
Stack remains green: 222/222 FastVideo unit/contract/api tests pass; 8/8
Playwright e2e tests pass against the live `dreamverse-server` + Next.js
stack.
---
## Repo + branch state
| Repo | Path | Branch | Tip |
| --- | --- | --- | --- |
| FastVideo | `/home/william5lin/FastVideo` | `will/ltx2_sr_port` | `c6c14c55` |
| Dreamverse | `/home/william5lin/Dreamverse` | `will/integrate-public-fastvideo` | `3d7fd89` |
| Reference (read-only) | `/home/william5lin/FastVideo-internal` | (their) `main` | source of truth for parity |
> **Working branch on FastVideo is `will/ltx2_sr_port`, not the default checkout.**
> The shell may report `will/uv-pip-install-everywhere` because that was
> the earlier checkout. Run `git checkout will/ltx2_sr_port` before
> picking up FastVideo work.
### Live processes (do not duplicate)
```
:8009 dreamverse-server pid 2453227 (warmed, /readyz returns 200)
:5274 next-server (dev) pid 2399103 (devtools build)
```
### Stashes
* FastVideo: `stash@{0}: WIP on main: …HunyuanVideo plugin…` — pre-existing,
unrelated to this work, do not pop.
* Dreamverse: `stash@{0}: wip: server modular refactor (split
config/prompting/runtime/session)` — 3867 lines of orphan modular split
off this branch. Do not pop on this branch; recover on a separate
feature branch if anyone wants to resurrect it.
---
## What landed (FastVideo: `cfccd292..c6c14c55`)
Six commits on top of the i2v / continuation latent port:
```
c6c14c55 test(nvfp4): lock LTX-2 wiring + typed transformer_quant flow
94c983a2 refactor(quant): rename FP4 → NVFP4 to disambiguate from other FP4 variants
42b30bf9 feat(ltx2): wire FP4 inference through fastvideo.layers.quantization
6da342ba feat(compile): per-component compile + transformer_refine + prepare hook
221cb20a feat(api): typed per-component CompileConfig + FastVideoArgs carriers
a4760bae fix(api): propagate generic refine_* args + match internal randn
```
Each commit message has the rationale. Highlights below.
### `a4760bae` — three small parity fixes
* `FastVideoArgs.__post_init__` now calls `_resolve_refine_args()` which
copies the public-facing generic `refine_*` knobs onto their
`ltx2_refine_*` runtime carriers. Was missing → callers that set
`refine_lora_path=...` saw "applied to 0 layers" warnings as the value
was silently dropped.
* `_randn_ltx2_video_latents` patch path reverted from `randn_tensor` →
`torch.randn` to bit-match internal under single-generator inference.
Identical for a single `torch.Generator` but diverges for
`list[Generator]` (per-sample seeds).
* Classified 19 `refine_*` / `ltx2_refine_*` / i2v / `ltx2_audio_*` /
`ltx2_conditioning_latent_*` / `ltx2_video_conditions` fields in the
schema-parity inventory yaml.
### `221cb20a` — typed CompileConfig + FastVideoArgs carriers
`CompileConfig` (in `fastvideo/api/schema.py`) gained per-component knobs:
```python
@dataclass
class CompileConfig:
enabled: bool = False # master DiT switch
backend / fullgraph / mode / dynamic / extras # master kwargs
# Per-component overlays, None = inherit master `enabled`
text_encoder_enabled: bool | None = None
vae_enabled: bool | None = None
audio_vae_enabled: bool | None = None
# Per-component kwargs override master when non-empty
dit_kwargs: dict = ...
text_encoder_kwargs: dict = ...
vae_kwargs: dict = ...
audio_vae_kwargs: dict = ...
```
Matching carrier fields on `FastVideoArgs`:
`enable_torch_compile_text_encoder/vae/audio_vae` and
`torch_compile_kwargs_dit/text_encoder/vae/audio_vae`. Compat layer
round-trips them through `legacy_from_pretrained_to_config` and
`generator_config_to_fastvideo_args`. **No behavior change yet** — these
are surface ports only; consumed in the next commit.
### `6da342ba` — refine + per-component compile + prepare_for_compile
`composed_pipeline_base.post_init` now:
* compiles `transformer_refine` alongside `transformer` and
`transformer_2` whenever the DiT compile flag is on (closes the LTX-2
stage-2 silent-eager bug);
* dispatches per-component compile loops (text encoder, VAE, audio VAE)
with per-component kwargs falling back to master when empty;
* calls `module.prepare_for_compile()` on each compiled submodule
before invoking `torch.compile` (hook protocol — model-specific).
Implemented on `Gemma3` to materialize HF weights outside Dynamo's
tracer.
### `42b30bf9` — NVFP4 LTX-2 inference wire-up *(largest)*
End-to-end:
1. `models/dits/ltx2.py` — swap `nn.Linear` → `ReplicatedLinear` for the
FP4-eligible subset (`LTXSelfAttention`, `LTXDistributedSelfAttention`,
`FeedForward`/`GELUApprox`); plumb `quant_config` and `prefix=` from
`BasicAVTransformerBlock` → `_init_transformer_blocks` → `LTXModel`
→ `LTX2Transformer3DModel`. Other linears
(`TimestepEmbedding`, `PixArtAlphaTextProjection`, `patchify_proj`,
`proj_out`, `AdaLayerNormSingle.linear`) stay `nn.Linear` —
matches internal exactly.
2. Port `_supports_prequantized_input` and
`_linear_project_with_optional_prequant` helpers. Attention forward
pre-quantizes input once (`quantize_input`), reuses the
`(x_fp4, x_scale, x_global_sf)` tuple for k/v projections when
`context is x` — bit-matches internal's fused path.
3. `models/loader/fsdp_load.py` — new `_maybe_convert_model_to_nvfp4`
helper detects via `isinstance(quant_method, NVFP4QuantizeMethod)`
(no flag); calls `convert_model_to_nvfp4` to materialize
`_nvfp4_weight*` / `_nvfp4_alpha` / `_weight_global_sf` buffers.
`flashinfer` import is lazy (inside the helper), so the loader is a
no-op on hosts without flashinfer.
4. `layers/quantization/__init__.py` — registered `"NVFP4"` in
`QuantizationMethods` literal + `get_quantization_config`.
5. `api/compat.py` + `fastvideo_args.py` — typed
`engine.quantization.transformer_quant: "NVFP4"` resolves to a
concrete `NVFP4Config()` instance, carried on `FastVideoArgs.transformer_quant`,
pinned onto `pipeline_config.dit_config.quant_config` in
`__post_init__._apply_transformer_quant`. **The explicit setter
(legacy mutation pattern) wins** if `dit_config.quant_config` is
already non-None.
6. `layers/linear.py` — `LinearBase.__init__` now falls back to
`UnquantizedLinearMethod` when `quant_config.get_quant_method` returns
`None`. `NVFP4Config` only tags a curated subset of LTX-2 layers, and
the previous `assert quant_method is not None` would crash any
non-tagged layer that received a quant_config.
### `94c983a2` — FP4 → NVFP4 rename
NVIDIA's specific block-scaled fp4 format (e2m1 mantissa, fp32 alpha,
`layout_128x4` scale layout, group size 16) — distinct from MX-FP4 /
OCP-FP4 / generic e3m0. Mechanical rename, no behavior change:
* `fp4_config.py` → `nvfp4_config.py`
* `FP4Config` → `NVFP4Config`; `get_name()` returns `"nvfp4"`
* `FP4QuantizeMethod` → `NVFP4QuantizeMethod`
* `convert_model_to_fp4` → `convert_model_to_nvfp4`
* `QuantizationMethods` literal: `"FP4"` → `"NVFP4"`
* registered buffer names: `_fp4_weight`/`_fp4_alpha` →
`_nvfp4_weight`/`_nvfp4_alpha`
* loader helper renamed
* test file rename + symbol updates
Internal-scope torch op namespace `fastvideo_fp4::*` and
`_get_ltx2_fp4_stage_profile` deliberately left as-is — purely
internal naming that mirrors FastVideo-internal.
### `c6c14c55` — contract + numerical lock-in tests
* `fastvideo/tests/ops/quantization/test_nvfp4_ltx2_wiring.py` (6 tests):
asserts that `LTXSelfAttention.to_q/to_k/to_v/to_out` are
`ReplicatedLinear`; `NVFP4Config()` attaches `NVFP4QuantizeMethod`
on the quantized subset with the correct `layer_prefix`; non-tagged
projections (cross-attn K/V, audio attn, audio FFN) fall back to
`UnquantizedLinearMethod`; `BasicAVTransformerBlock` propagates
`quant_config` and `prefix` correctly to all 4 attention modules +
FFN at once.
* `fastvideo/tests/api/test_typed_quant_flow.py` (4 tests): asserts
typed `engine.quantization.transformer_quant: "NVFP4"` →
`NVFP4Config()` instance flow; default leaves `transformer_quant`
None; explicit `dit_config.quant_config = …` wins over typed carrier.
---
## What landed (Dreamverse: `248060b..3d7fd89`)
Three commits on top of the e2e tier:
```
3d7fd89 feat(skill): launch-demo orchestrator + fastvideo serve YAML
d80c2a8 refactor(server): drive FP4 + per-component compile via typed GeneratorConfig
4cc6b30 chore: gitignore Playwright + Next.js build artifacts under apps/web
```
### `d80c2a8` — server/video_generation.py refactor
Three coordinated changes in the GPU worker:
* Replace legacy `load_kwargs` dict + `VideoGenerator.from_pretrained(model_root, **kwargs)`
call with the typed `GeneratorConfig` (`EngineConfig` /
`OffloadConfig` / `CompileConfig` / `PipelineSelection` /
`ComponentConfig`). Refine knobs move from `ltx2_refine_*` flat
kwargs into `preset_overrides["refine"]`. **The in-memory
`pipeline_config` pin** (`dit_config.quant_config = NVFP4Config()`)
keeps using the legacy `experimental["pipeline_config"]` carrier
because typed `transformer_quant: "NVFP4"` doesn't yet support
setting `layer_profile`.
* Rename FP4 → NVFP4.
* Re-enable `"mode": "max-autotune-no-cudagraphs"` (was commented out).
Closes the last known divergence vs FastVideo-internal in the
worker-level path trace.
### `4cc6b30` — gitignore Playwright/Next.js artifacts
Added `apps/web/{node_modules,.next,test-results,playwright-report}` to
`.gitignore`. Mirror of the existing `prod-ui/` ignore set.
### `3d7fd89` — launch-demo skill
```
.agents/skills/launch-demo/
├── SKILL.md
└── scripts/
├── launch_demo.sh # orchestrator: BE + FE + health probes + Ctrl-C trap
├── launch_backend_dreamverse.sh # uv run dreamverse-server (default)
├── launch_backend_fastvideo.sh # uv run fastvideo serve --config (typed path)
└── launch_frontend.sh # next dev (devtools/dev/single5s)
serve_configs/
└── streaming_demo.yaml # canonical ServeConfig matching internal/ui
```
YAML has every field annotated with the internal source line it mirrors:
LTX-2 distilled, NVFP4, 121 frames @ 1088×1920 24fps, 5 inference steps,
2-step refine gs=1.0 add_noise=true, max-autotune-no-cudagraphs compile,
121-frame default request, 300s session timeout, 6 segment cap, av_fmp4
streaming, cinematic-drone warmup prompt, 2400s warmup timeout, 9
conditioning frames + 0 end-offset, prompt enhancer on with cerebras /
gpt-oss-120b / 20s timeout.
**Two BE flavors documented in SKILL.md:**
| `BE_FLAVOR=` | Boots | Routes served | FE compatible |
| --- | --- | --- | --- |
| `dreamverse` (default) | `dreamverse-server` | `/healthz`, `/readyz`, `/curated-presets`, `/v1/stream`, devtools, session monitor | ✓ full |
| `fastvideo` | `fastvideo serve --config <yaml>` | `/health`, `/v1/stream` | ⚠ FE will surface fetch errors for `/curated-presets`, `/readyz` until those routes migrate into FastVideo's `build_app` |
The fastvideo flavor exists today as the verifiable typed-config path
(YAML parses, streaming worker boots, dotted overrides work). It is not
yet a drop-in for the FE — see "Open follow-ups" below.
---
## Verified
* `222 passed, 1 skipped` across `fastvideo/tests/api/`,
`fastvideo/tests/contract/`,
`fastvideo/tests/ops/quantization/test_nvfp4_*`,
`tests/local_tests/pipelines/test_ltx2_pipeline_smoke.py`.
* `8 passed` Playwright e2e (backend-health 5, frontend-shell 2,
preset-prompt-generation 1) against the live `dreamverse-server`
+ Next.js stack.
* `streaming_demo.yaml` parses cleanly against `ServeConfig`; the
validation path of `fastvideo serve --config <yaml>` runs without
error and accepts dotted overrides like `--server.port 8010`.
* FastVideo `bash -n` clean across all four launch scripts.
---
## Critical context (gotchas a successor should know)
### NVFP4 layer set is asymmetric — by design
`NVFP4Config.fp4_layers` covers:
* `attn1.{to_q,to_k,to_v,to_out}` — full self-attention
* `attn2.{to_q,to_out}` — cross-attn Q + out only (text context not quantized)
* `audio_to_video_attn.{to_q,to_out}` — AV cross Q + out
* `video_to_audio_attn.{to_k,to_v}` — VA cross K + V
* `ffn.{fc_in,fc_out}` — video FFN
* `adaln_single.linear` — but this is `nn.Linear` (not `LinearBase`),
so it never actually gets FP4'd. List entry has no effect; matches
internal.
**NOT in the set:** audio self-attention (`audio_attn1.*`), audio
cross-attention (`audio_attn2.*`), audio FFN (`audio.ffn.*`). Audio
path is cheap enough that quant overhead isn't worth it. Test
`test_basic_av_block_propagates_quant_config_to_all_children` locks
this in — if you add audio quantization later, update the test.
### `LinearBase` fallback is load-bearing
`fastvideo/layers/linear.py:191-202`: when `quant_config.get_quant_method`
returns `None` (layer not in the quant config's set), we fall back to
`UnquantizedLinearMethod`. **Do not remove this fallback** — it would
break every non-tagged `ReplicatedLinear` constructed with a
`NVFP4Config`, and `assert quant_method is not None` in
`ReplicatedLinear.__init__` would fire on unmatched layers.
### Typed `transformer_quant` precedence
`FastVideoArgs._apply_transformer_quant` only writes
`dit_config.quant_config` when it's currently `None`. If a caller has
explicitly set `pipeline_config.dit_config.quant_config = NVFP4Config(...)`,
the explicit setter wins. Dreamverse's `video_generation.py` relies on
this — it sets `NVFP4Config()` directly because the typed
`transformer_quant: "NVFP4"` doesn't expose `layer_profile`.
### Pre-existing AbsMaxFP8 test failure is NOT mine
`fastvideo/tests/ops/quantization/test_absmax_fp8.py::test_create_weights_rejects_invalid_dtype`
fails on `main` and on this branch with the same error
("AssertionError not raised"). I confirmed via `git stash` that the
failure pre-dates my changes. Not blocking; tracked as separate tech
debt.
### `transformer_refine` is auto-compiled with the master DiT flag
Set `enable_torch_compile=True` and `transformer_refine` compiles
along with `transformer` and `transformer_2`. There is **no separate
`enable_torch_compile_refine` flag** — by design, refine inherits the
DiT compile state to keep the typed surface small. If you need them
decoupled, add a new field; don't repurpose existing ones.
### `prepare_for_compile` is a duck-type protocol, not a base class method
Defined nowhere; called via `getattr(module, "prepare_for_compile", None)`
in `composed_pipeline_base._maybe_compile_pipeline_module`. Currently
only Gemma implements it (to materialize HF weights outside Dynamo).
Add to other models that have lazy external state if you observe
compile-time graph breaks.
### Public typed `PromptEnhancerConfig.provider` is `Literal["cerebras", "groq"]`
Internal supports `"cerebras_ifm"` (config.py:143). The public typed
schema does not. The `streaming_demo.yaml` defaults to `"cerebras"`.
For agents that need `cerebras_ifm`, the `dreamverse-server` flavor
respects the `FASTVIDEO_PROMPT_PROVIDER` env var (legacy path);
`fastvideo serve --config` does not currently expose it.
### Dreamverse `pipeline_config` is still a Python object passed via `experimental`
The typed `GeneratorConfig` doesn't have a clean home for an
in-memory `PipelineConfig` instance with mutated `dit_config`. We
pass it via `pipeline.experimental["pipeline_config"]` — the
`compat.py` legacy adapter recognizes that key and threads it through
to `FastVideoArgs.from_kwargs`. This is fine but not pretty; if
someone designs a typed `dit_config` carrier later, this becomes
obsolete.
### `fastvideo serve --config` is not yet a drop-in for the FE
`fastvideo.entrypoints.streaming.server.build_app` exposes only
`/health` and `/v1/stream`. The Dreamverse Next.js shell expects
`/healthz`, `/readyz`, `/status`, `/curated-presets`,
`/curated-presets/append`, `/prompt-system-config`, and the devtools
routes. These all live in `Dreamverse/server/main.py` +
`Dreamverse/server/routes/`. Until they migrate into FastVideo's
`build_app` (or are exposed via a Dreamverse-side proxy), the
`BE_FLAVOR=fastvideo` flavor is for verifying the typed serve config
path only — not for full FE compatibility.
---
## Open follow-ups (prioritized)
### High
1. **Migrate FE-required routes into FastVideo's `build_app`.**
`/healthz`, `/readyz`, `/status` look obviously fastvideo-side
(they're streaming-server health). `/curated-presets` and
`/prompt-system-config` are operator-side surfaces and should
probably stay in Dreamverse (or migrate as opt-in routes that the
FE feature-detects). Without this, `BE_FLAVOR=fastvideo` is
permanently a "diagnostic" flavor. Closes the
`launch-demo` skill TODO.
2. **AbsMaxFP8 test failure cleanup.** Pre-existing. Either fix the
test (`AbsMaxFP8LinearMethod.create_weights` no longer asserts on
invalid dtype — restore the assert if intentional, otherwise drop
the test).
### Medium
3. **Add `cerebras_ifm` to public `PromptEnhancerConfig.provider`
Literal.** Trivial schema change; needs paired enhancer-side
provider implementation in
`fastvideo/entrypoints/streaming/prompt/providers/`.
4. **Expose `layer_profile` on typed `engine.quantization`.** Today
`transformer_quant: "NVFP4"` always constructs `NVFP4Config()`
with the default `layer_profile="refine"`. To support stage-1
profiles (no `attn2.to_out`, no cross-modal AV) via typed config,
add `transformer_quant_layer_profile: str | None = None` and
thread it through `compat.py`. Dreamverse currently dodges this
by setting `NVFP4Config()` directly via `experimental`.
5. **Typed `dit_config.quant_config` carrier.** The
`experimental["pipeline_config"]` escape hatch in Dreamverse
should eventually become a typed field. Design TBD.
### Low
6. **Audio attention quantization profile.** If an audio-quant
profile is added to `NVFP4Config.fp4_layers` (currently audio attn
and FFN are bf16), update
`test_basic_av_block_propagates_quant_config_to_all_children`.
7. **Schema parity inventory.** A few internal-only fields are not
exposed publicly (`PROMPT_HTTP_TIMEOUT_MS`,
`PROMPT_INITIAL_STAGE_TIMEOUT_MS`, `PROMPT_TEMPERATURE`,
`PROMPT_MAX_COMPLETION_TOKENS`, `PROMPT_AUTO_SLEEP_MS`,
`PROMPT_AUTO_TIMEOUT_MS`, the curated-presets file paths).
These all flow via env vars on `dreamverse-server` today; if
`fastvideo serve --config` becomes the canonical entrypoint,
they'll need typed homes.
8. **Empty `apps/web/test-results/` directory locally.** The
`.gitignore` entry I added makes it invisible to `git status`,
but the dir itself still has a stale `.last-run.json` (45 bytes)
from a prior Playwright run. Harness blocked auto-cleanup
("pre-existing files"); the user can `rm -rf
apps/web/test-results` whenever convenient.
---
## How to pick up work
### Quick orientation (run these first)
```bash
# FastVideo state
cd /home/william5lin/FastVideo
git checkout will/ltx2_sr_port
git log --oneline cfccd292..HEAD # six commits added this round
.venv/bin/python -m pytest fastvideo/tests/api/ \
fastvideo/tests/contract/ \
fastvideo/tests/ops/quantization/test_nvfp4_*.py \
tests/local_tests/pipelines/test_ltx2_pipeline_smoke.py \
-q --no-header # expect 222 passed, 1 skipped
# Dreamverse state
cd /home/william5lin/Dreamverse
git log --oneline 248060b..HEAD # three commits added this round
cat serve_configs/streaming_demo.yaml | head -40
ls .agents/skills/launch-demo/
# Live stack health (already running on this host)
curl -s http://localhost:8009/readyz | head -c 200
curl -s http://localhost:5274/ | head -c 100
( cd apps/web && npx playwright test --reporter=line ) # expect 8 passed
```
### Reference docs
* **FastVideo internal/ui parity source:** `../FastVideo-internal/ui/ltx2-streaming/server/config.py`
* **NVFP4 source on internal:** `../FastVideo-internal/fastvideo/layers/quantization/fp4_config.py`
* **Worker-trace audit:** `../FastVideo/dreamverse_review.md` (D-1
multi-model, D-5 audio re-encode, prior gap inventory)
* **Schema parity inventory:** `docs/design/inference_schema_parity_inventory.yaml`
* **PR-plan for the broader migration:** `../FastVideo/PR plan.md`
### Files most likely to need touches in follow-ups
* `fastvideo/api/schema.py` — `CompileConfig`, `QuantizationConfig`,
`PromptEnhancerConfig` Literal extension.
* `fastvideo/api/compat.py` — typed → flat translation.
* `fastvideo/fastvideo_args.py` — carrier fields and
`_apply_transformer_quant`.
* `fastvideo/entrypoints/streaming/server.py::build_app` — add
`/healthz`, `/readyz`, `/status` routes for FE compatibility (high
priority follow-up #1).
* `Dreamverse/server/video_generation.py` — typed `GeneratorConfig`
builder (current).
* `Dreamverse/serve_configs/streaming_demo.yaml` — every parity
knob; edit here, not in shell scripts.
---
## Don't / Cautions
* **Don't pop the Dreamverse stash on this branch.** It's 3867 lines
of orphan modular refactor (server/{config,prompting,runtime,session}/)
with broken absolute imports. If anyone wants to resurrect it, do so
on a separate feature branch.
* **Don't remove the `LinearBase` `UnquantizedLinearMethod` fallback.**
See "Critical context" above.
* **Don't repurpose `enable_torch_compile` to mean DiT-only.** It also
drives `transformer_refine` and `transformer_2` compile. Add a new
flag if decoupling is needed.
* **Don't change `NVFP4Config` buffer names back to `_fp4_*`.** The
rename is intentional to disambiguate from MX-FP4 / OCP-FP4.
* **Don't bypass the typed surface for new options.** New compile /
quant / refine knobs should land on the dataclass + compat.py +
parity inventory together. The existing test suite locks this in.
* **Don't merge to main without a CI run that covers FP4.** Current
CI doesn't run flashinfer-dependent paths; the wiring tests in
`test_nvfp4_ltx2_wiring.py` are CPU-only by design and don't
exercise the actual FP4 kernels.
---
*Last updated: end of session that landed `c6c14c55` on FastVideo and
`3d7fd89` on Dreamverse. Stack remains green; no dirty state.*
@@ -1,539 +0,0 @@
# FastVideo Streaming Server Upstream — Design & Plan
## Status
Exploration / design draft. Captures the re-evaluation triggered by the
decision to upstream `FastVideo-internal/ui/ltx2-streaming/server/` into
the public repo. Not yet approved for execution.
## Related Documents
- [PR plan.md](../../PR%20plan.md) — PR-by-PR implementation plan for the API refactor
- [apirefactor.md](../../apirefactor.md) — design spec this plan implements
- `../../../FastVideo-internal/ui/ltx2-streaming/` — upstream source (server side)
- `../../../dynamo/` — local clone of ai-dynamo/dynamo; backend patterns at
`components/src/dynamo/{vllm,sglang,trtllm}/` and `CLAUDE.md` files
- https://github.com/ai-dynamo/dynamo/pull/7544 — draft PR that promotes
FastVideo to a native Dynamo backend (CLOSED, superseded — but establishes
the integration shape)
## Context
The internal `FastVideo-internal/ui/ltx2-streaming/` directory contains a
complete LTX2 streaming service. The user has decided:
- **Frontend clients** (`client/`, `prod-ui/`) stay in the internal repo
- **Everything server-side** — FastAPI/WebSocket server, GPU pool, prompt
enhancer, router, auxiliaries — will be upstreamed to FastVideo
In parallel, FastVideo is becoming a **first-class Dynamo backend** (same
tier as vllm, sglang, trtllm). The refactor must produce an API that
Dynamo's `components/src/dynamo/fastvideo/` package can consume as a
pure Python import, without re-introducing the legacy flat-kwarg
surface. Draft PR ai-dynamo/dynamo#7544 defines the concrete integration
shape we need to support.
This materially changes the tail of the API refactor plan. The current
PR 5 ("wire `ServeConfig.default_request` into the OpenAI-compatible
HTTP server") addresses only the stateless endpoint; the real upstream
target is a much larger, session-based stack **plus** a clean Dynamo
backend contract.
This document captures:
- what's being upstreamed and where it lands
- four design decisions that shape the upstream (continuation model,
streaming server layout, LLM provider abstraction, Dynamo backend
integration)
- a revised PR sequence for the tail of the refactor
## What's being upstreamed
| Internal path | Size | Role | Upstream target |
|---|---|---|---|
| `server/main.py` | 94KB | FastAPI + WebSocket, session lifecycle, segment orchestration | `fastvideo/entrypoints/streaming/server.py` + handlers |
| `server/gpu_pool.py` | 66KB | GPU orchestration, subprocess workers | `fastvideo/entrypoints/streaming/gpu_pool.py` |
| `server/prompt_enhancer.py` | 69KB | LLM orchestration (cerebras_ifm, cerebras, groq) | `fastvideo/entrypoints/streaming/prompt/` package |
| `server/mock_server.py` | 45KB | Mock backend for dev/tests | `fastvideo/entrypoints/streaming/mock_server.py` |
| `server/prompt_safety.py` | 7KB | Optional fasttext-gated prompt safety | `fastvideo/entrypoints/streaming/prompt/safety.py` |
| `server/session_init_image.py` | 3KB | i2v init image handling | `fastvideo/entrypoints/streaming/session_init_image.py` |
| `server/rewrite_prompt_payload.py` | 3KB | Rewrite flow payload builder | `fastvideo/entrypoints/streaming/prompt/rewrite.py` |
| `server/session_logger.py` | 1KB | Session JSONL logs | `fastvideo/entrypoints/streaming/session_logger.py` |
| `server/config.py` | 9KB | Env-driven server config | Typed `ServeConfig` extensions |
| `router/main.py` | 27KB | Multi-replica load balancer + WS proxy | `fastvideo/entrypoints/streaming/router/` (or separate package) |
| `slurm/` | — | Deployment scripts | Likely stays internal |
## FastVideo contact surface today
Direct calls from the internal stack into FastVideo, all in `gpu_pool.py`:
| Location | Call | Notes |
|---|---|---|
| `gpu_pool.py:164` | `from fastvideo.entrypoints.video_generator import VideoGenerator` | Subprocess-level import, post-`CUDA_VISIBLE_DEVICES` setup |
| `gpu_pool.py:230` | `PipelineConfig.from_pretrained(config_model_path)` | Direct access to legacy `PipelineConfig` |
| `gpu_pool.py:231` | `pipeline_config.dit_config.quant_config = FP4Config()` | Direct internals mutation |
| `gpu_pool.py:264-267` | `VideoGenerator.from_pretrained(model_root, **load_kwargs)` | Flat legacy kwargs |
| `gpu_pool.py:837` | `generator.generate_video(**request_kwargs)` | Per-segment flat kwargs |
| `gpu_pool.py:282-288` | `LTX2AudioEncoder`, `AudioProcessor`, `get_diffusers_config` | Audio re-encode path |
`load_kwargs` at `gpu_pool.py:233-260` contains:
`ltx2_refine_enabled`, `ltx2_refine_upsampler_path`, `ltx2_refine_lora_path`,
`ltx2_refine_num_inference_steps`, `ltx2_refine_guidance_scale`,
`ltx2_refine_add_noise`, `pipeline_config`, `torch_compile_kwargs`,
`dit_cpu_offload`, `dit_layerwise_offload`, `vae_cpu_offload`,
`text_encoder_cpu_offload`, `pin_cpu_memory`, `ltx2_vae_tiling`,
`use_fsdp_inference`, `enable_torch_compile`.
`request_kwargs` at `gpu_pool.py:837` includes:
`ltx2_audio_clean_latent`, `ltx2_audio_denoise_mask`,
`ltx2_video_conditions`, `video_position_offset_sec`, standard sampling
fields.
**Implication**: upstreaming `gpu_pool.py` as-is perpetuates the flat
kwarg surface inside the public server. We need a typed translation
(PR 6 expansion) at the worker boundary before, or as part of, the
gpu_pool upstream.
## Session / continuation semantics today
Per-session state (in `server/main.py`):
- `locked_segment_prompts`, `curated_prompts`, `segment_idx`,
`generated_segment_count`, `loop_iteration`
Per-**GPU** (not per-session) continuation cache (in `gpu_pool.py`):
- `ltx2_continuation_images` — last 9 decoded frames for clip conditioning
- `ltx2_continuation_audio_latents` — denoised audio latents for audio conditioning
Segment N+1 automatically conditions on segment N's trailing frames and
audio. On session reset or handoff (`USER_JOIN`), the per-GPU cache is
cleared. There is currently **no way for a client to serialize and
resume continuation state elsewhere** — it lives on the GPU only.
## Design Decision 1: Continuation model
### Options
**A. Opaque client-round-trip payload** (current plan PR 7 design)
- Server returns `ContinuationState(kind, payload)`; client sends it back.
- Pro: stateless server, trivially load-balanceable, survives disconnects.
- Con: large payloads (frames + audio latents) over every request hop;
bandwidth heavy on multi-segment WebSocket sessions.
**B. Server-held session state** (internal reality)
- Continuation lives per-GPU; implicit between adjacent segments.
- Pro: zero client bandwidth; fast; matches today.
- Con: needs GPU affinity, no resume after disconnect, harder to scale horizontally.
**C. Hybrid** (recommended)
- Server-held is the default for streaming WebSocket sessions.
- Server exposes a `snapshot_state` message that returns the opaque
payload form for migration/retry.
- Stateless HTTP endpoints always use round-trip opaque payloads.
- One serialization format underlies both surfaces.
### Decision: **C (Hybrid)**
Rationale: matches both internal streaming use (server-held, fast) and
stateless API use (client-round-trip, resumable). Cost is one serialization
layer that serves both.
### Implications
- `ContinuationState.kind` identifies the payload schema
(e.g. `"ltx2.v1"`).
- `ContinuationState.payload` must cover:
- trailing conditioning frames (or a tensor reference)
- audio latents (or a tensor reference)
- segment index / rollout position
- any model-specific conditioning metadata (e.g. audio sample rate,
`video_position_offset_sec`)
- For large tensors, payload may reference a server-side blob by ID
rather than inline everything.
- Streaming server has a `SessionStore` keyed by session ID that holds
a typed `LTX2ContinuationState` object.
- `SessionStore.snapshot(session_id) -> ContinuationState` serializes
the current state for export.
- `SessionStore.hydrate(state: ContinuationState) -> session_id` loads
a state into a new session.
- Plan PR 7 expands to cover both surfaces and define the payload schema.
## Design Decision 2: Streaming server layout
### Options
- **A. `fastvideo/entrypoints/streaming/`** — parallel to
`fastvideo/entrypoints/openai/`
- **B. `fastvideo/entrypoints/server/{stateless,streaming}/`** — reorg both
- **C. `fastvideo/streaming/`** — top-level package, not under entrypoints
### Decision: **A (parallel subpackage)**
Rationale: lowest-friction, no existing code moves, both servers share
the same `fastvideo/entrypoints/*` namespace and import style. Shared
utilities can be factored into `fastvideo/entrypoints/server_common/`
later if needed. Option B creates churn across every openai/ import for
marginal organizational win.
### Target layout
```text
fastvideo/entrypoints/
├── openai/ # existing: stateless HTTP POST
│ ├── api_server.py
│ ├── video_api.py
│ ├── image_api.py
│ ├── common_api.py
│ ├── protocol.py
│ ├── state.py
│ ├── stores.py
│ └── utils.py
├── streaming/ # NEW: session WebSocket
│ ├── server.py # FastAPI + WebSocket entry
│ ├── session.py # session lifecycle, state machine
│ ├── session_store.py # typed session state + snapshot/hydrate
│ ├── protocol.py # JSON WebSocket message schemas
│ ├── stream.py # fMP4 encoding (av_fmp4 mode)
│ ├── gpu_pool.py # subprocess workers
│ ├── worker.py # per-GPU worker loop
│ ├── continuation.py # typed LTX2 state payload
│ ├── session_init_image.py
│ ├── session_logger.py
│ ├── mock_server.py
│ ├── prompt/
│ │ ├── enhancer.py # provider-agnostic prompt ops
│ │ ├── rewrite.py
│ │ ├── safety.py # optional fasttext
│ │ ├── payload.py # rewrite payload builder
│ │ └── providers/
│ │ ├── base.py # LLMProvider protocol
│ │ ├── cerebras.py
│ │ ├── cerebras_ifm.py
│ │ └── groq.py
│ └── router/ # or separate top-level package
│ ├── main.py
│ └── registry.py
├── cli/ # existing
└── video_generator.py # existing
```
### Config integration
`ServeConfig` gets an optional `streaming: StreamingConfig | None` field:
```python
@dataclass
class StreamingConfig:
session_timeout_seconds: int = 300
generation_segment_cap: int = 6
stream_mode: Literal["av_fmp4", "legacy_jpeg"] = "av_fmp4"
warmup: WarmupConfig = field(default_factory=WarmupConfig)
pool: GpuPoolConfig = field(default_factory=GpuPoolConfig)
prompt: PromptEnhancerConfig | None = None
safety: PromptSafetyConfig | None = None
@dataclass
class GpuPoolConfig:
num_workers: int | None = None # default: CUDA_VISIBLE_DEVICES count
enable_audio_reencode: bool = True
conditioning_num_frames: int = 9
conditioning_end_offset: int = 0
@dataclass
class PromptEnhancerConfig:
provider: Literal["cerebras_ifm", "cerebras", "groq"] = "cerebras_ifm"
model: str = "gpt-oss-120b"
timeout_ms: int = 20000
system_prompt_dir: str | None = None # hot-reloadable system prompts
@dataclass
class PromptSafetyConfig:
enabled: bool = False
classifier_path: str | None = None
```
## Design Decision 3: LLM provider abstraction
### Problem
`prompt_enhancer.py` (69KB) hard-codes three providers (cerebras_ifm,
cerebras, groq) with provider-specific request/response handling
scattered throughout. Upstreaming as-is locks FastVideo to those three
providers and couples the prompt operations to their response shapes.
### Shape
Introduce an `LLMProvider` protocol:
```python
from typing import Protocol, AsyncIterator, Literal
from dataclasses import dataclass
@dataclass
class LLMMessage:
role: Literal["system", "user", "assistant"]
content: str
@dataclass
class LLMRequest:
messages: list[LLMMessage]
model: str
max_tokens: int | None = None
temperature: float | None = None
timeout_ms: int | None = None
@dataclass
class LLMResponse:
content: str
provider: str
model: str
latency_ms: float
fallback_used: bool = False
class LLMProvider(Protocol):
name: str
async def complete(self, request: LLMRequest) -> LLMResponse: ...
```
### Decision: **Protocol + built-in implementations for cerebras, cerebras_ifm, groq**
Rationale: keeps the prompt enhancer free of provider-specific branching;
users (and future OpenAI/Anthropic/local additions) can register their
own provider without modifying FastVideo. Each built-in provider is
100-200 LOC; the enhancer becomes provider-agnostic prompt orchestration.
### Implications
- `prompt_enhancer.py` splits into `enhancer.py` (prompt operations) +
`providers/` (IO).
- Config moves from scattered env vars to typed `PromptEnhancerConfig`
under `ServeConfig.streaming.prompt`.
- Hot-reloadable system prompts stay — exposed as a management endpoint
on the streaming server.
- Fallback behavior (retry across providers in priority order) moves
into the enhancer layer, orthogonal to provider implementations.
## Design Decision 4 preamble: what Dynamo expects from FastVideo
Dynamo's backend pattern (observed in
`dynamo/components/src/dynamo/sglang/` and confirmed by PR #7544) is a
**pure Python import** pattern. Dynamo owns the backend subpackage in its
own repo; FastVideo only needs to expose a stable, typed, aggregated
and (later) streaming generation surface.
### Contract surface Dynamo consumes
| Surface | Shape | Notes |
|---|---|---|
| Constructor | `VideoGenerator.from_pretrained(model_path, **typed_kwargs)` | Already exists; `typed_kwargs` must be a stable subset from `GeneratorConfig` — no flat LTX2 legacy kwargs. |
| Sync execution | `generator.generate_video(request: GenerationRequest) -> VideoResult` | Aggregated mode; Dynamo wraps in `asyncio.to_thread` under an `asyncio.Lock`. |
| Async execution | `generator.generate_async(request: GenerationRequest) -> AsyncGenerator[VideoEvent, None]` | Needed for: (a) streaming server fMP4 chunks; (b) future Dynamo disaggregation. Events: `Progress`, `Partial?`, `Final`. |
| Typed request | `fastvideo.api.GenerationRequest`, `SamplingConfig`, `InputConfig` | Stable import path; Dynamo's adapter builds this from `NvCreateVideoRequest` + `VideoNvExt`. |
| Typed result | `VideoResult` with `video_bytes` or tensor frames, plus `ContinuationState?` | Must be picklable / JSON-serializable enough for Dynamo RPC. |
| Continuation | `ContinuationState(kind, payload)` with schema-versioned payloads | Used by FastVideo's session store today; tomorrow by Dynamo disaggregated workers. |
| Health check input | `VideoGenerator.default_health_check_request() -> GenerationRequest` | Minimal 256x256 / 8 frames / 1 step; lets Dynamo's `FastVideoHealthCheckPayload.to_dict()` produce the Dynamo `health_check_payload` kwarg without knowledge of FastVideo internals. |
| Config dump | `GeneratorConfig.to_dict()` / `ServeConfig.to_dict()` | Dynamo calls `dynamo.common.config_dump.dump_config(path, config)` at worker start; we already have `config_to_dict()`. |
### Request/response mapping (Dynamo ↔ FastVideo)
Dynamo's video protocol (`NvCreateVideoRequest` / `NvVideosResponse`):
```
NvCreateVideoRequest -> fastvideo.api.GenerationRequest
prompt -> sampling.prompt
size="WxH" -> sampling.width, sampling.height
seconds -> (seconds * nvext.fps) -> sampling.num_frames
input_reference -> input.image_path / input.video_path
nvext.fps -> sampling.fps
nvext.num_frames -> sampling.num_frames (overrides seconds*fps)
nvext.num_inference_steps -> sampling.num_inference_steps
nvext.guidance_scale -> sampling.guidance_scale
nvext.seed -> sampling.seed
nvext.negative_prompt -> sampling.negative_prompt
response_format -> (handled by adapter at output)
VideoFinalEvent -> NvVideosResponse
video_bytes -> data[0].b64_json (if response_format=b64_json)
video_url (after upload) -> data[0].url (if response_format=url)
metadata.inference_time_s -> inference_time_s
```
All fields already exist (or will exist after PR 6 expansion) on
FastVideo's typed schema. No FastVideo changes required beyond what the
rest of this plan already covers **except**:
1. `generate_async` must exist (new in PR 7.10).
2. `default_health_check_request()` helper (new in PR 7.10).
3. The sync `generate_video(request=...)` path must be reachable without
extra wrapping (exists since PR 2; confirm stability).
### Where the Dynamo subpackage lives
The Dynamo-side integration (`FastVideoHandler`, `register_fastvideo_model`,
`FastVideoHealthCheckPayload`, args parsing, main.py, Dockerfile,
request/response mapping) lives **entirely in the Dynamo repo** at
`components/src/dynamo/fastvideo/`, matching the pattern used by vllm
and sglang. FastVideo does **not** host any Dynamo-related subpackage,
Dynamo dependency, or Dynamo-specific CLI. FastVideo's only obligation
is to expose a clean, stable, typed Python API that Dynamo's backend
package can import.
## Design Decision 4: Dynamo as first-class backend target
### Problem
PR #7544 (closed) shows two frictions with the pre-refactor API:
1. **Flat legacy kwargs** — the Dynamo handler had to know about
LTX2-specific flat names.
2. **Sync-only generation** — Dynamo's async handler wrapped
`generator.generate(...)` in `asyncio.to_thread` under a lock; no
progress streaming, no disaggregation path.
The refactor's stateless OpenAI server, WebSocket streaming server, and
Dynamo backend all want the same thing: **a typed async API that yields
progress events and a typed final result**. If we build it once in
`VideoGenerator`, all three adapters become thin.
### Options
**A. Keep sync-only, each adapter wraps**
- Simple; matches PR #7544.
- Con: streaming server needs its own async runner; Dynamo loses progress
streaming; no path to disaggregation.
**B. Add async event stream to `VideoGenerator`**
- `generate_async(request) -> AsyncGenerator[VideoEvent, None]`.
- Sync `generate_video` becomes a thin `asyncio.run` wrapper internally.
- Pro: one canonical execution API; streaming server, OpenAI server,
and Dynamo all consume events directly.
- Con: larger delta in `VideoGenerator` — must thread async through the
pipeline step loop.
**C. Queue-based `generate(request, event_cb)` callback**
- Middle ground; callback receives events.
- Pro: no async rewrite needed.
- Con: callers have to invert control; awkward for Dynamo's async
handler.
### Decision: **B (async event stream)**
Rationale: one substrate serves all three consumers. The cost is a
`generate_async` implementation that runs the pipeline step loop in a
thread and bridges events back via an asyncio queue — standard pattern,
limited surface area.
### Implications
- New PR 7.10 adds `generate_async` on `VideoGenerator` with three event
types: `VideoProgressEvent(step, total_steps, stage)`,
`VideoPartialEvent(frames_ndarray, index)` (optional; emitted only in
the streaming path), `VideoFinalEvent(video_bytes_or_tensor, metadata,
continuation_state?)`.
- Sync `generate_video(request=...)` becomes `asyncio.run(...)` over
`generate_async`, collecting events and returning the final.
- Streaming server's fMP4 encoder consumes `VideoPartialEvent` frames
directly, never re-decoding through disk.
- Dynamo adapter consumes `generate_async` and yields one
`NvVideosResponse` per `VideoFinalEvent` (aggregated mode; ignores
intermediate events today; can surface progress via Dynamo's
status/progress fields in the future).
- `ContinuationState` can be attached to `VideoFinalEvent.metadata`,
giving Dynamo a first-class way to surface state for disaggregation
later.
- Stable public exports: `from fastvideo import VideoGenerator`;
`from fastvideo.api import GenerationRequest, SamplingConfig,
ContinuationState, VideoResult, VideoEvent`.
- No Dynamo subpackage, dep, or CLI lives in FastVideo. The adapter
(`NvCreateVideoRequest ↔ GenerationRequest` mapping, handler,
registration) lives entirely in the Dynamo repo at
`components/src/dynamo/fastvideo/`.
### Constraints this adds to earlier PRs
- **PR 6** (typed LTX2 kwargs): every flat kwarg must have a typed home
**reachable from `GeneratorConfig`**, so Dynamo can construct the
generator without importing internal compat paths.
- **PR 7** (continuation state): `ContinuationState.payload` must be
JSON/YAML serializable (no raw torch tensors inline; use blob
indirection) so it survives Dynamo RPC transport.
- **PR 7.5** (streaming skeleton): consume `generate_async` rather than
re-implementing a progress loop around `generate_video`.
- **PR 2/3/4 already landed**: the typed request shape is fixed and
matches Dynamo's mapping needs — no backtracking required.
## Revised PR sequence (PR 5 onwards)
PRs 0-4 are unchanged and already landed. PR 5 is narrowed; PRs 5.5-7.9
are new inserts; PRs 8-13 are reshaped or kept.
| # | Title | Change | Key deliverables |
|---|---|---|---|
| **5** | Stateless `ServeConfig.default_request` merge | **Narrowed.** Wire typed default-request into `fastvideo/entrypoints/openai/`. | `_merge_default_request` helper, validated-against-preset, tests for default+user-override precedence |
| **5.5** | Server architecture split | **NEW.** Introduce `fastvideo/entrypoints/streaming/` subpackage skeleton. No behavior change. | Empty subpackage + stub server.py; CLI subcommand `fastvideo streaming-serve` (raises NotImplementedError); doc on layout |
| **6** | LTX2 public preset + stage overrides + config colocation | **Expanded.** Also add typed replacements for every flat kwarg used by internal `gpu_pool.py`. | `ltx2_two_stage` preset, `LTX2RefineStageOverride`, `CompileConfig` field types, typed `FP4Config` integration, colocation |
| **7** | Continuation state (public + session) | **Expanded.** Define both opaque payload AND server-held session store. | `ContinuationState.payload` schema, `LTX2ContinuationState` typed subclass, `SessionStore` interface, snapshot/hydrate APIs |
| **7.5** | Streaming server skeleton | **NEW.** Minimum viable WebSocket server: session lifecycle, JSON messages, fMP4 output, single-generator. | `server.py`, `session.py`, `protocol.py`, `stream.py` (fMP4), typed `StreamingConfig` |
| **7.6** | GPU pool upstream | **NEW.** Upstream `gpu_pool.py` with typed config boundary. | `gpu_pool.py`, `worker.py`, job queue, session-to-GPU binding, session timeout handling |
| **7.7** | Prompt enhancer upstream | **NEW.** Upstream `prompt_enhancer.py` with `LLMProvider` abstraction. | `prompt/enhancer.py`, `prompt/providers/{base,cerebras,cerebras_ifm,groq}.py`, hot-reloadable system prompts |
| **7.8** | Streaming auxiliaries | **NEW.** Small, isolated. | `prompt/safety.py`, `session_init_image.py`, `prompt/rewrite.py`, `session_logger.py`, `mock_server.py` |
| **7.9** | Router upstream | **NEW.** Multi-replica load balancer + WS proxy. | `streaming/router/` (or separate top-level package), health checks, WS proxy |
| **7.10** | Dynamo backend contract | **NEW.** Add `VideoGenerator.generate_async` event stream + `default_health_check_request()` helper. FastVideo exposes the async API only; the Dynamo backend package (handler, adapter, registration) lives entirely in the Dynamo repo at `components/src/dynamo/fastvideo/`. Streaming server (PR 7.5) and Dynamo backend both consume the same async API. | `generate_async` with `VideoProgressEvent`/`VideoPartialEvent`/`VideoFinalEvent`; sync `generate_video` becomes a thin wrapper; contract tests against a mock Dynamo-style handler that imports only public FastVideo APIs |
| **8** | Internal-UI ↔ public-server contract docs & tests | **Reframed.** Was "Dreamverse Server Adaptation Layer." Also covers Dynamo integration reference. | WebSocket protocol reference, contract tests, migration examples, Dynamo adapter example that upstream PR can copy verbatim |
| **9** | LongCat preset migration + colocation | **Keep.** | Stage overrides, colocation |
| **10** | Hunyuan15 SR preset migration + colocation | **Keep.** | Stage overrides, SR field migration POC, colocation |
| **11** | SSIM / perf test migration | **Keep.** Now blocked on PR 6 expansion. | Typed API migration of golden tests |
| **12** | Docs + examples | **Keep, expand.** | Streaming server docs now part of scope |
| **13** | Deprecation + cleanup | **Keep, expand.** | Also deprecate flat kwargs that internal gpu_pool uses today |
Total PR count: 13 → ~20 (13 original + 5 streaming-upstream inserts +
1 architecture split + 1 Dynamo contract). Each new PR is small and
self-contained because the streaming components are already cleanly
separated in the internal repo, and the Dynamo contract rides on top of
the async API that the streaming server already needs.
## Open questions
1. **Router: in-repo or separate package?** — It's orthogonal to inference;
in-repo couples deploy cycles, separate leaves FastVideo cleaner.
Recommendation: separate package `fastvideo-router/` or
`fastvideo/contrib/router/`; defer final call to PR 7.9.
2. **Session ID authority** — internal uses ad-hoc client IDs.
Recommendation: server-generated UUID, accept externally provided
session ID only for resume flows.
3. **Torch compile kwargs typing** — `CompileConfig.kwargs: dict[str, Any]`
today accepts `mode`, `backend`, `fullgraph`, `dynamic`. Options: keep
as opaque dict; fully type; hybrid (type the common four + allow
extras). Recommendation: hybrid, type common fields.
4. **Prompt safety / fasttext dependency** — heavy for users who don't
need it. Recommendation: ship as optional extra
`pip install fastvideo[prompt-safety]`.
5. **Audio-specific tensor payloads** — `ltx2_audio_clean_latent`,
`ltx2_audio_denoise_mask`, `ltx2_audio_latents` are not in the current
public schema. PR 7 should classify them (probably as opaque fields
inside `LTX2ContinuationState.payload`, not top-level sampling fields).
6. **Batching behavior** — internal `test_batching.py` suggests batching
is exercised. Scope this into PR 7.5 or defer to a post-cleanup perf PR?
7. ~~**Dynamo subpackage home**~~ — **Resolved.** No Dynamo code lives
in FastVideo. The full backend package (handler, adapter,
registration, health check) is owned by the Dynamo repo at
`components/src/dynamo/fastvideo/`, same pattern as vllm/sglang.
FastVideo only guarantees the public API contract listed above.
8. **Disaggregation readiness** — PR #7544 is aggregated-only. Our
`ContinuationState` hybrid already supports a future prefill/decode
split (prefill yields state; decode hydrates it). Should PR 7.10
explicitly validate that `ContinuationState` survives round-trip
through a Dynamo-style RPC (pickle or JSON), even though Dynamo
isn't using it today? Recommendation: yes; cheap contract test that
prevents drift.
9. **Dynamo progress/status passthrough** — `NvVideosResponse` has
`status` and `progress` fields. Should PR 7.10's handler contract
emit intermediate `NvVideosResponse` chunks keyed off
`VideoProgressEvent`, or stay aggregated-final-only to match PR
#7544? Recommendation: stay aggregated-final for PR 7.10; revisit
after Dynamo clarifies their streaming/progress semantics.
## Immediate path forward
1. Land `will/api_5` cleanup commits — **done** (`e03ca7d9`, `41f93179`
force-pushed without Claude co-author).
2. Review this plan with a human — commit the doc to capture the state.
3. Execute PR 5 (narrow stateless merge) and PR 5.5 (subpackage split)
in parallel. Both small; both unblock the streaming upstream that
follows.
4. Start PR 6 expansion (typed replacements for flat LTX2 kwargs) as the
critical path for PR 7.6 (gpu_pool upstream).
@@ -1,93 +0,0 @@
# Exploration Log: Video Generator Config API Design
## Status: draft
## Context
FastVideo's Python inference API currently mixes generator-instance settings,
pipeline initialization settings, and per-request sampling/runtime settings
through broad `**kwargs` surfaces on `VideoGenerator.from_pretrained(...)` and
`VideoGenerator.generate_video(...)`.
This exploration compares the current FastVideo design with
`sglang/multimodal_gen` and examines how to upstream multi-stage LTX2 /
Dreamverse behavior without growing more ad hoc top-level flags.
## Progress
- [x] Read FastVideo onboarding, codebase map, and relevant design docs.
- [x] Inspect current FastVideo generator, args, sampling, registry, and
workflow abstractions.
- [x] Inspect internal LTX2 streaming server usage and current two-stage /
continuation requirements.
- [x] Inspect SGL diffusion generator, server args, sampling params, and
request preparation boundary.
- [x] Inspect vLLM-Omni stage config, stage metadata, request, and orchestration
surfaces for multi-stage pipeline ideas.
- [x] Inspect current FastVideo CLI/config-file loading and compare with the
training YAML-only entrypoint.
- [ ] Convert findings into a concrete implementation plan for FastVideo.
## Findings
- FastVideo already has the right internal separation points:
`FastVideoArgs`, `PipelineConfig`, `SamplingParam`, and `ForwardBatch`.
- The public boundary is the unstable part:
init-time and request-time knobs are mixed through `**kwargs`.
- Unknown init keys can be silently filtered, while unknown request keys can be
only logged rather than rejected. This makes API drift hard to detect.
- SGL's split is cleaner:
`ServerArgs` for engine/runtime, `PipelineConfig` for model-family wiring,
and `SamplingParams` for per-request settings.
- SGL also has better merge semantics for user request overrides:
it preserves model defaults, tracks explicitly provided fields, and validates
request params against pipeline task type.
- SGL still has a design smell worth avoiding in FastVideo:
`SamplingParams._adjust(...)` depends on `ServerArgs`, which leaks
engine/pipeline concerns back into the request object.
- vLLM-Omni contributes a useful extra abstraction beyond SGL:
model-owned multi-stage topology via `ModelPipeline` and `StageConfig`,
with per-stage defaults (`default_sampling_params`) and runtime override
layering.
- vLLM-Omni's best reusable idea for FastVideo is not the serving stack, but
the separation between:
1. model-defined stage topology and per-stage defaults,
2. runtime engine overrides,
3. request-time sampling/state handoff.
- vLLM-Omni also shows the downside of exposing stage-indexed request lists too
directly: `sampling_params_list` works for a serving engine, but is too
positional and low-level for FastVideo's higher-level Python API.
- FastVideo already supports YAML/JSON config files for inference CLI, but the
current mechanism flattens nested documents back into argparse flags. This
preserves backward compatibility but keeps the CLI surface as the canonical
schema instead of a typed document model.
- The training stack has a cleaner precedent: a YAML-first config loaded into a
typed schema, with dotted CLI overrides applied onto the nested document
before parsing. Inference can likely adopt a lighter variant of that pattern.
- Multi-stage generation should be unified at the orchestration layer, not by
forcing LongCat refine, Hunyuan SR, and LTX2 continuation into one leaf config.
## Mistakes / Dead Ends
- A fully free-form string-dict API would lose too much type safety and would
likely recreate the current drift problem under a different shape.
- A single universal `RefineConfig` for all models would become a sparse bag of
nullable fields and would not map cleanly to existing model families.
## Proposed Standardization
- Introduce a typed public split:
`GeneratorConfig` for instance-lifetime engine/init settings and
`GenerationRequest` for per-call inputs/sampling/output.
- Allow dict input only as an interchange layer that is parsed immediately into
typed configs with strict unknown-key validation.
- Add a typed `GenerationPlan` / multi-stage orchestration layer with
discriminated stage configs:
`SampleStageConfig`, `LongCatRefineStageConfig`,
`HunyuanSRStageConfig`, `LTX2ContinuationStageConfig`.
- Let model families own stage defaults and stage topology through named
profiles or model-defined stage plans, similar in spirit to vLLM-Omni's
pipeline YAMLs, but expose them through typed Python config objects rather
than raw stage-indexed lists in the primary API.
- Make YAML/JSON a first-class serialization of the same typed inference
schema, not just a file format that expands into CLI flags.
- Prefer a YAML-first CLI pattern for nested configs:
`fastvideo generate --config run.yaml --request.sampling.seed 42`,
while keeping a compatibility layer for existing flat flags during migration.
- Upstream LTX2 two-stage / continuation behavior as a first-class stage or
pipeline profile rather than more `ltx2_*` top-level kwargs.
@@ -1,194 +0,0 @@
# Current State — 2026-05-05 (strategy reversal — single mega-PR #1288)
Point-in-time snapshot of branches, commits, and live infrastructure.
Update whenever commits land or services restart.
For HOW to commit / push / verify see [runbook.md](runbook.md). For
roster of co-authors to credit on every commit see
[authors.md](authors.md).
## Branch tips
| Repo | Branch | Tip | Distance |
|---|---|---|---|
| FastVideo | `will/ltx2_sr_port` (**PR #1288 head**) | `b36bdbc9` | 36 commits ahead of `origin/main`; OPEN, MERGEABLE; +integration-review.md (Part 1 drift + Part 2 tradeoffs + recommended Option D) |
| FastVideo | `will/api_7.10` | `6ae7a99f` | **deprecated** — PR #1287 closed in favor of #1288. Branch can be deleted on origin and locally; kept for now as historical reference. |
| FastVideo | `will/api_8`, `will/ltx2_sr_runtime`, `will/ltx2_nvfp4`, `will/ltx2_post_fixes`, `will/agents_cleanup` | (various) | **deprecated** split bookmarks. Strategy reversed to single mega-PR (D-17). Safe to delete locally; not pushed to origin. |
| FastVideo | `will/ltx2_sr_port-pre-1286-rebase` | `1baa60bb` | **local-only safety backup** of pre-rebase chain (37 commits); keep until next slice merges |
| Dreamverse | `will/integrate-public-fastvideo` | `ec8ef92` | 10 commits ahead of `737f3c1` (the dep switch) |
| FastVideo-internal | their `main` | (read-only ref) | — |
FastVideo worktree default branch is `will/ltx2_sr_port`. Other agents
share this worktree — if `git branch --show-current` shows something
else, switch back cleanly with `git checkout will/ltx2_sr_port` (don't
disturb their uncommitted work). I observed this happen repeatedly in
the 2026-05-05 session — confirmed harmless; switching back was always
safe with a clean working tree.
## Post-#1286 rebase summary
PR #1286 merged at `2aaeee2a` (squash). `will/ltx2_sr_port` was rebased
onto new `origin/main`, dropping 4 commits whose content is now in main:
- `cd76cf51` `[feat] streaming: router (multi-replica load balancer)`
- `1ac1e732` `[feat] streaming: fastvideo router-serve CLI`
- `b0b7f59c` `[test] streaming: router registry + health loop ...`
- `40e265b8` `[fix] streaming: router polish — bridge cancel + state
machine + deps` (squashed into `2aaeee2a` via cherry-pick `a152cb77`)
Rebase was clean — no conflicts. All 33 surviving commits got new SHAs
(rebase rewrites). The pre-rebase tip `1baa60bb` is preserved on the
local backup branch `will/ltx2_sr_port-pre-1286-rebase`.
## New linearized chain (33 commits, slice indices for STACK.md)
| Slice | PR | Commits | Tip SHA | Subject |
|---|---|---|---|---|
| 1-3 | 7.10 (PR #1287) | 3 | `6ae7a99f` | `[test] streaming: generate_async coverage + refreshed streaming test` |
| 4-6 | 8 | 3 | `f32e31ec` | `[test] streaming: contract tests for Dreamverse + Dynamo shapes` |
| 7-15 | LTX-2 SR | 9 | `e7297519` | `feat(ltx2): full i2v conditioning + continuation latent port` |
| 16-21 | NVFP4 | 6 | `6793166b` | `test(nvfp4): lock LTX-2 wiring + typed transformer_quant flow` |
| 22-23 | LTX-2 post-fixes | 2 | `25897b67` | `[fix]: unwrap list-of-generator before torch.randn in LTX-2 latent prep` |
| 24-33 | agents_cleanup | 10 | `b34d9704` | `[docs] dreamverse-integration: add runbook + fresh-context onboarding` |
5 PRs landed (7.5, 7.6, 7.7, 7.8, 7.9), 1 in flight (7.10), 5 remaining
(8 / LTX-2 SR / NVFP4 / post-fixes / agents_cleanup).
## Historical commit chain analysis (pre-#1286 rebase)
The layered chain analysis below documented the pre-rebase SHAs (LTX-2
SR layer, NVFP4 layer, post-handoff fixes layer). Those SHAs no longer
exist on `will/ltx2_sr_port` — they live only on
`will/ltx2_sr_port-pre-1286-rebase`. Content semantics are unchanged;
SHAs were rewritten by the rebase. Kept here for narrative continuity.
## FastVideo: commit chain `cfccd292..156103b9`
Three layers since LTX-2 i2v port:
### Layer 1 — LTX-2 SR port + alignment harness (5 commits)
```
365a66c7 feat(quantization): upstream LTX-2 FP4Config with lazy flashinfer
433d26b2 feat(ltx2): port LTX-2 SR runtime — upsampler, refine stages, refine args
751d05de feat(ltx2): wire SR pipeline graph + port denoising/latent-prep stages
af6bbfea test(ltx2-sr): add numerical alignment harness — public vs internal
974cd430 fix(ltx2-sr): close port gaps surfaced by alignment harness retries
b6ac7630 test(ltx2-sr): pin ltx2 sampling knobs in harness for parity diff
b043d550 fix(api): align public SamplingParam ltx2 defaults with distilled
663dda80 fix(registry): order LTX-2 detectors so distilled wins for distilled paths
cfccd292 feat(ltx2): full i2v conditioning + continuation latent port (BASE)
```
(Predates the May 2 handoff.)
### Layer 2 — NVFP4 wire-up + per-component compile (6 commits, May 2 handoff)
```
a4760bae fix(api): propagate generic refine_* args + match internal randn
221cb20a feat(api): typed per-component CompileConfig + FastVideoArgs carriers
6da342ba feat(compile): per-component compile + transformer_refine + prepare hook
42b30bf9 feat(ltx2): wire FP4 inference through fastvideo.layers.quantization
94c983a2 refactor(quant): rename FP4 → NVFP4 to disambiguate from other FP4 variants
c6c14c55 test(nvfp4): lock LTX-2 wiring + typed transformer_quant flow
```
See [quantization.md](quantization.md) for what each commit locks in.
### Layer 3 — Post-handoff parity/perf fixes (3 commits, since May 2)
```
a5fcd19c [fix]: lazy-import flash_attn 2 fallback in attention backend
d4ee5be2 [fix]: avoid model.to() round-trip in Gemma encoder forward
156103b9 [fix]: unwrap list-of-generator before torch.randn in LTX-2 latent prep (HEAD)
```
Three small fixes — no new features. Continued parity tightening with internal.
## Dreamverse: commit chain `737f3c1..ec8ef92`
```
737f3c1 chore: switch fastvideo dep from FastVideo-internal to public FastVideo
4cc6b30 chore: gitignore Playwright + Next.js build artifacts under apps/web
33caa92 test(e2e): align Playwright specs with the actual production composer
6fd137c test(e2e): tighten frontend-shell + preset specs to match actual UI
248060b test(e2e): add Playwright tier with backend-health smoke + preset run
d80c2a8 refactor(server): drive FP4 + per-component compile via typed GeneratorConfig
3d7fd89 feat(skill): launch-demo orchestrator + fastvideo serve YAML
72f69b9 Update ffmpeg installation instructions.
1ba5635 fix(server): block startup on GPU warmup readiness, propagate failures
ec8ef92 fix(server): detect worker death in _send_command via proc.sentinel (HEAD)
```
The post-handoff trio (`72f69b9`, `1ba5635`, `ec8ef92`) hardens server
startup robustness — ffmpeg install docs, GPU warmup readiness gate, and
worker-death detection.
## Live services (do not duplicate)
| Port | Service | PID | Status |
|---|---|---|---|
| 8009 | `dreamverse-server` | 2453227 | `/readyz` returns 200, 1 warmed GPU worker, queue 0 |
| 5274 | `next-server` (dev) | 2399103 | 200, ~13.6 KB shell |
| 8000 | unknown FastAPI | — | **Not in handoff.** Probably stray `fastvideo serve`. Verify with `lsof -i :8000` before launching a new BE on the default port. |
## Stashes — DO NOT POP
| Repo | Stash | Reason |
|---|---|---|
| FastVideo | `stash@{0}: WIP on main: 71bfc13d HunyuanVideo plugin` | Pre-existing, unrelated to integration work |
| Dreamverse | `stash@{0}: wip: server modular refactor (split config/prompting/runtime/session)` | 3867-line orphan modular split, **not part of `will/integrate-public-fastvideo`**. Recover on a separate branch if needed. |
## Test status (from May 2 handoff, not re-verified post-Layer-3)
| Suite | Status |
|---|---|
| FastVideo `fastvideo/tests/api/` + `contract/` + `nvfp4_*` + `ltx2_pipeline_smoke` | 222 passed, 1 skipped |
| Playwright e2e against live BE+FE | 8 passed (5 backend-health + 2 frontend-shell + 1 preset-prompt-generation) |
| `fastvideo serve --config streaming_demo.yaml` validation | parses cleanly; dotted overrides work |
| `bash -n` on launch-demo skill scripts | clean across all 4 |
The 3 post-handoff commits are small parity fixes; full re-verification is
recommended but not required to read this state.
## Pre-existing failures (NOT caused by this work)
| Test | Failure | Notes |
|---|---|---|
| `fastvideo/tests/ops/quantization/test_absmax_fp8.py::test_create_weights_rejects_invalid_dtype` | `AssertionError not raised` | Pre-existing on `main`. Verified via `git stash` that NVFP4 work doesn't introduce it. See [open-threads.md](open-threads.md) item #2. |
## Source docs (archived 2026-05-03)
The 7 source docs that this memory dir consolidates have been moved into
[`source-archive/`](source-archive/) — see the
[archive README](source-archive/README.md) for the archive policy and
synthesis mapping.
Other untracked items at the FastVideo repo root:
- Nested clones: `dynamo/`, `ray/`, `vllm-omni/`
- Lock files: `uv.lock`, `fastvideo/tests/ssim/.reference_videos_download.lock`
- Skill dirs: `.agents/skills/diagnose-ssim-failure/`, `.agents/skills/review-pr-link/`
- `.agents/exploration/pr-link-review.md` (kept; already promoted to a skill)
## Quick orientation commands
```bash
# FastVideo state
cd /home/william5lin/FastVideo
git log --oneline cfccd292..HEAD # 14 commits this round
# Dreamverse state
cd /home/william5lin/Dreamverse
git log --oneline 737f3c1..HEAD # 10 commits this round
# Live stack health (already running)
curl -s http://localhost:8009/readyz | head -c 300
curl -s http://localhost:5274/ -o /dev/null -w "%{http_code}\n"
# Re-verify test suite
.venv/bin/python -m pytest fastvideo/tests/api/ \
fastvideo/tests/contract/ \
fastvideo/tests/ops/quantization/test_nvfp4_*.py \
tests/local_tests/pipelines/test_ltx2_pipeline_smoke.py \
-q --no-header
```
@@ -1,389 +0,0 @@
# Streaming Server Upstream — PRs 5.5 → 7.10
The `FastVideo-internal/ui/ltx2-streaming/server/` stack is being
upstreamed into public FastVideo at `fastvideo/entrypoints/streaming/`.
In parallel, FastVideo is becoming a first-class Dynamo backend (same
tier as vllm, sglang, trtllm). This file covers both threads since they
share `generate_async` as the substrate.
For PR sequence/status see [pr-roadmap.md](pr-roadmap.md). For the
Dreamverse-side adoption see [cross-repo-surfaces.md](cross-repo-surfaces.md).
**Last updated:** 2026-05-03.
## What's being upstreamed
| Internal path | Size | Role | Public target |
|---|---|---|---|
| `server/main.py` | 94 KB | FastAPI + WebSocket, session lifecycle, segment orchestration | `fastvideo/entrypoints/streaming/server.py` + handlers |
| `server/gpu_pool.py` | 66 KB | GPU orchestration, subprocess workers | `fastvideo/entrypoints/streaming/gpu_pool.py` |
| `server/prompt_enhancer.py` | 69 KB | LLM orchestration (cerebras_ifm, cerebras, groq) | `fastvideo/entrypoints/streaming/prompt/` package |
| `server/mock_server.py` | 45 KB | Mock backend for dev/tests | `fastvideo/entrypoints/streaming/mock_server.py` |
| `server/prompt_safety.py` | 7 KB | Optional fasttext-gated prompt safety | `prompt/safety.py` |
| `server/session_init_image.py` | 3 KB | i2v init image handling | `streaming/session_init_image.py` (PR 7.5, already public) |
| `server/rewrite_prompt_payload.py` | 3 KB | Rewrite flow payload builder | `prompt/rewrite.py` |
| `server/session_logger.py` | 1 KB | Session JSONL logs | `streaming/session_logger.py` |
| `server/config.py` | 9 KB | Env-driven server config | typed `ServeConfig.streaming` extensions |
| `router/main.py` | 27 KB | Multi-replica load balancer + WS proxy | `fastvideo/entrypoints/streaming/router/` |
| `slurm/` | — | Deployment scripts | Stays internal |
Frontend clients (`client/`, `prod-ui/`) stay in the internal repo.
## Four design decisions that shape the upstream
### D-1: Continuation model — Hybrid (server-held + opaque client-round-trip)
Streaming WebSocket sessions hold continuation per-GPU (matches today's
internal behavior, fast, zero client bandwidth). Stateless HTTP endpoints
use opaque round-trip payloads. Server exposes a `snapshot_state` message
that returns the opaque form for migration/retry.
One serialization layer underlies both surfaces.
Implementation: `SessionStore` (in-memory default, pluggable for
redis/etc.) keyed by session ID, holds typed `LTX2ContinuationState`.
- `snapshot(session_id) -> ContinuationState` exports for migration
- `hydrate(state: ContinuationState) -> session_id` loads state into new session
Payload schema covers: trailing conditioning frames (or tensor-blob ID),
audio latents (or blob ID), segment index, audio sample rate,
`video_position_offset_sec`, model-specific metadata.
Landed in PR 7. See [cross-repo-surfaces.md](cross-repo-surfaces.md) for
the full wire format.
### D-2: Streaming server layout — Parallel subpackage `fastvideo/entrypoints/streaming/`
Sits next to `fastvideo/entrypoints/openai/`. No existing code moves.
Both servers share the `entrypoints/*` namespace. Shared utilities can be
factored into `fastvideo/entrypoints/server_common/` later if needed.
### D-3: LLM provider abstraction — `LLMProvider` protocol + built-in providers
`prompt_enhancer.py` (69 KB) hard-coded three providers (cerebras_ifm,
cerebras, groq) with provider-specific request/response handling
scattered throughout. Upstreaming as-is would lock FastVideo to those
providers.
Protocol shape:
```python
@dataclass
class LLMRequest:
messages: list[LLMMessage]
model: str
max_tokens: int | None = None
temperature: float | None = None
timeout_ms: int | None = None
@dataclass
class LLMResponse:
content: str
provider: str
model: str
latency_ms: float
fallback_used: bool = False
class LLMProvider(Protocol):
name: str
async def complete(self, request: LLMRequest) -> LLMResponse: ...
```
PR 7.7 ships built-in providers for cerebras, groq. **Public Literal
currently restricts to `Literal["cerebras", "groq"]`** — `cerebras_ifm`
is internal-only and remains environment-driven on `dreamverse-server`.
See [open-threads.md](open-threads.md) follow-up #3.
Hot-reloadable system prompts via management endpoint. Sequential
fallback across providers in priority order — race-based fallback (the
internal optimization) deferred per [decisions-log.md](decisions-log.md)
D-3.
### D-4: Dynamo as first-class backend target — async event stream
PR ai-dynamo/dynamo#7544 (closed draft) showed two frictions:
1. Flat legacy kwargs — Dynamo handler had to know LTX-2-specific names.
2. Sync-only generation — Dynamo wrapped `generator.generate(...)` in
`asyncio.to_thread` under a lock; no progress streaming, no
disaggregation path.
Decision: **add `generate_async`** as the canonical execution API.
```python
async def generate_async(
self,
request: GenerationRequest,
) -> AsyncGenerator[VideoEvent, None]: ...
```
Events:
```python
@dataclass
class VideoProgressEvent:
step: int
total_steps: int
stage: str # "denoise" | "refine" | "decode" | ...
@dataclass
class VideoPartialEvent:
frames: np.ndarray # (num_frames, H, W, 3)
index: int # monotonic chunk index
@dataclass
class VideoFinalEvent:
video_bytes: bytes | None
tensor: torch.Tensor | None
metadata: dict[str, Any]
continuation_state: ContinuationState | None
```
The sync `generate_video(request=...) -> VideoResult` becomes a thin
`asyncio.run` wrapper over `generate_async` that collects events and
returns the final.
**Three consumers, one substrate:**
| Consumer | Transport | Request shape | State |
|---|---|---|---|
| Stateless OpenAI (`fastvideo/entrypoints/openai/`) | HTTP POST | `GenerationRequest` merged onto `ServeConfig.default_request` | Stateless; opaque payload |
| Streaming WebSocket (`fastvideo/entrypoints/streaming/`) | WebSocket JSON + binary fMP4 | `GenerationRequest` per segment, session-scoped | Server-held; per-GPU continuation cache |
| Dynamo native backend (`ai-dynamo/dynamo/components/src/dynamo/fastvideo/`) | Dynamo RPC endpoint | `NvCreateVideoRequest` ↔ adapter ↔ `GenerationRequest` | Aggregated today; future disaggregated via `ContinuationState` |
**FastVideo does NOT host any Dynamo code.** The full backend package
(`args.py`, `main.py`, `backend.py`, `register.py`, `health_check.py`)
lives entirely in the Dynamo repo at `components/src/dynamo/fastvideo/`,
matching the vllm/sglang pattern. FastVideo's only obligation is the
stable public Python API.
PR 7.10 lands the FastVideo-side contract. Dynamo backend code lives in
ai-dynamo/dynamo (next iteration of #7544 reopens against PR 8 reference
docs).
## Target package layout
```
fastvideo/entrypoints/
├── openai/ # existing: stateless HTTP POST
├── streaming/ # NEW: session WebSocket
│ ├── server.py # FastAPI + WebSocket entry
│ ├── session.py # session lifecycle, state machine
│ ├── session_store.py # typed session state + snapshot/hydrate
│ ├── protocol.py # JSON WebSocket message schemas
│ ├── stream.py # fMP4 encoding (av_fmp4 mode)
│ ├── gpu_pool.py # subprocess workers (PR 7.6)
│ ├── worker.py # per-GPU worker loop
│ ├── continuation.py # typed LTX2 state payload
│ ├── session_init_image.py
│ ├── session_logger.py
│ ├── mock_server.py
│ ├── prompt/
│ │ ├── enhancer.py # provider-agnostic prompt ops
│ │ ├── rewrite.py
│ │ ├── safety.py # optional fasttext
│ │ └── providers/
│ │ ├── base.py # LLMProvider protocol
│ │ ├── cerebras.py
│ │ ├── cerebras_ifm.py
│ │ └── groq.py
│ └── router/
│ ├── main.py
│ └── registry.py
├── cli/
└── video_generator.py
```
## Typed config integration
`ServeConfig` gets an optional `streaming: StreamingConfig | None`:
```python
@dataclass
class StreamingConfig:
session_timeout_seconds: int = 300
generation_segment_cap: int = 6
stream_mode: Literal["av_fmp4", "legacy_jpeg"] = "av_fmp4"
warmup: WarmupConfig = field(default_factory=WarmupConfig)
pool: GpuPoolConfig = field(default_factory=GpuPoolConfig)
prompt: PromptEnhancerConfig | None = None
safety: PromptSafetyConfig | None = None
@dataclass
class GpuPoolConfig:
num_workers: int | None = None # default: CUDA_VISIBLE_DEVICES count
enable_audio_reencode: bool = True
conditioning_num_frames: int = 9
conditioning_end_offset: int = 0
@dataclass
class PromptEnhancerConfig:
provider: Literal["cerebras", "groq"] = "cerebras" # cerebras_ifm pending
model: str = "gpt-oss-120b"
timeout_ms: int = 20000
system_prompt_dir: str | None = None # hot-reloadable
@dataclass
class PromptSafetyConfig:
enabled: bool = False
classifier_path: str | None = None
```
## `build_app` route contract — open follow-up
Today `fastvideo.entrypoints.streaming.server.build_app` exposes only:
- `GET /health`
- `WS /v1/stream`
The Dreamverse Next.js shell expects these additional routes that the
upstream plan (and Dreamverse FE today) require:
| Route | Owner per upstream plan | Status |
|---|---|---|
| `GET /healthz` | Streaming-server-side health (FastVideo) | 🔴 NOT YET MIGRATED |
| `GET /readyz` | Streaming-server-side health (FastVideo) | 🔴 NOT YET MIGRATED |
| `GET /status` | Streaming-server-side health (FastVideo) | 🔴 NOT YET MIGRATED |
| `GET /curated-presets` | Operator-side surface (Dreamverse) | 🟡 stays in Dreamverse, FE feature-detects |
| `POST /curated-presets/append` | Operator-side surface (Dreamverse) | 🟡 stays in Dreamverse |
| `GET /prompt-system-config` | Operator-side surface (Dreamverse) | 🟡 stays in Dreamverse |
| Devtools routes | Dreamverse-only | 🟡 stays in Dreamverse |
Until the three health routes migrate into FastVideo's `build_app`, the
`BE_FLAVOR=fastvideo` flavor of `launch_demo.sh` is a "diagnostic" flavor
only (verifies typed serve-config path) — not FE-compatible. See
[open-threads.md](open-threads.md) follow-up #1.
The streaming-upstream plan listed `/healthz`, `/readyz`, `/status`,
`/ws` as the contract that the upstream of `realtime/` → `streaming/`
must preserve. They were deferred from PR 7.5's MVP.
## PR 7.5 status — open as #1251
Single-generator WebSocket end-to-end shipped (8 commits):
1. `feat(streaming): protocol schemas + session state machine`
2. `feat(streaming): fMP4 encoder + session init-image persistence`
3. `feat(streaming): single-generator WebSocket server entry`
4. `test(streaming): server lifecycle + protocol + fMP4 coverage`
5. `docs(streaming): server contract spec`
6. `fix(streaming): restore missing-streaming-block guard + retire stub-era test`
7. `simplify(streaming): review follow-ups (idle timeout via asyncio.wait_for, _send_error helper, _cleanup_session, Protocol-typed generator, cleanup-on-disconnect)`
8. `fix(streaming): enforce idle timeout on receive_json + flag generator-cancellation gap (TODO → PR 7.10)`
Deferred TODOs (intentionally) blocking on PR 7.10:
- **Per-step progress events** — only terminal `step_complete` today;
needs `generate_async` for per-step `VideoProgressEvent` emission.
- **Mid-segment cancellation on client disconnect** — TODO marker in
`server.py` near `pool.run`. Needs `generate_async`'s cancellation
propagation.
## PR 7.6 status — branch ready, not yet PR'd
`will/api_7.6` (5 commits, rebased on 7.5):
1. `feat [7.6/n]: GPU pool manager with typed worker boundary`
2. `refactor [7.6/n]: route streaming server through GpuPool`
3. `test [7.6/n]: GPU pool coverage (in-process + subprocess)`
4. `fix(streaming): restore missing asyncio import in server` (rebase fixup)
5. `feat(streaming): extract worker.py and add two-segment warmup`
Tests: 17/17 gpu_pool tests + 89/89 streaming tests green.
Ships:
- `GpuPool` ABC + `InProcessGpuPool` + `SubprocessGpuPool` +
`PoolAssignment` / `PoolHealth` / `PoolAcquireTimeout`
- `worker.py` — per-GPU `worker_main` and two-segment warmup helper
- Subprocess startup uses typed `GeneratorConfig`, NOT flat kwargs
- Session-to-GPU binding with timeout + queue for contention
- Two-segment startup warmup per worker (segment 1 fresh + segment 2
with returned `ContinuationState` so both compile branches are primed)
- `SessionStore` (from PR 7) wired for per-GPU continuation cache
Deferred to PR 7.10:
- **Audio re-encode (`LTX2AudioEncoder`, `AudioProcessor`)**: internal
`_re_encode_audio` runs *inside* the per-step streaming loop
(`_stream_av_fmp4_events` / `do_step_ltx2`). The whole-segment
`pool.run()` path PR 7.6 ships doesn't need it. Re-encode is a
per-step streaming concern that belongs with `generate_async`.
- **Deprecate `VideoGenerator.from_pretrained(**flat_kwargs)`**: belongs
with PR 13 cleanup.
## PR 7.10 — the unlock PR
PR 7.10 adds `generate_async` and closes three open threads
simultaneously:
- Q-5 / D-5: audio re-encode for cross-segment continuity
- Q-9: Dynamo progress passthrough
- PR 7.5's mid-segment cancellation TODO (client disconnect →
`asyncio.CancelledError` → GPU work stops)
Plus health-check helper:
```python
def default_health_check_request(self) -> GenerationRequest: ...
# Returns 256x256, 8 frames, 1 step. Lets Dynamo's
# FastVideoHealthCheckPayload.to_dict() produce a Dynamo
# health_check_payload kwarg without knowledge of FastVideo internals.
```
Stable public exports:
```python
from fastvideo import VideoGenerator
from fastvideo.api import (
GenerationRequest, SamplingConfig, ContinuationState,
VideoResult, VideoEvent,
VideoProgressEvent, VideoPartialEvent, VideoFinalEvent,
)
```
Streaming server (PR 7.5) gets rewired to consume `generate_async`
directly — no wrapper duplication.
## Dynamo request/response mapping
```
NvCreateVideoRequest -> fastvideo.api.GenerationRequest
prompt -> sampling.prompt
size="WxH" -> sampling.width, sampling.height
seconds -> seconds * nvext.fps -> sampling.num_frames
input_reference -> input.image_path | input.video_path
nvext.fps -> sampling.fps
nvext.num_frames -> sampling.num_frames (overrides seconds*fps)
nvext.num_inference_steps -> sampling.num_inference_steps
nvext.guidance_scale -> sampling.guidance_scale
nvext.seed -> sampling.seed
nvext.negative_prompt -> sampling.negative_prompt
response_format -> (handled at adapter's output stage)
VideoFinalEvent -> NvVideosResponse
video_bytes -> data[0].b64_json (response_format=b64_json)
uploaded URL -> data[0].url (response_format=url)
metadata.inference_time_s -> inference_time_s
continuation_state -> (reserved for future disaggregation)
```
## Open questions
1. **Router placement** — in-tree at `fastvideo/entrypoints/streaming/router/`
(current implementation per PR 7.9) or separate package
`fastvideo-router/` / `fastvideo/contrib/router/`. Effectively
resolved in-tree by the PR 7.9 implementation.
2. **Session ID authority** — server-generated UUID; accept externally
provided session ID only for resume flows.
3. **Disaggregation readiness contract test** — should PR 7.10 validate
`ContinuationState` survives round-trip through Dynamo-style RPC
(pickle or JSON), even though Dynamo isn't using it today?
Recommended: yes; cheap regression guard.
4. **Dynamo progress/status passthrough** — should PR 7.10's handler
contract emit intermediate `NvVideosResponse` chunks keyed off
`VideoProgressEvent`, or stay aggregated-final-only? Recommended:
stay aggregated-final for PR 7.10; revisit after Dynamo clarifies.
5. **`video_position_offset_sec` semantics** — see [decisions-log.md](decisions-log.md)
open question; needs decision before PR 7.6 emits state.
6. **`SessionStore` / `BlobStore` lifecycle** — eviction, TTL, blob-drop
on state replacement; defer to PR 7.5 design pass.
@@ -1,327 +0,0 @@
# Evaluation Metrics Registry
Living catalog of all evaluation metrics for FastVideo-WorldModel video quality
assessment. Each metric includes a detailed explanation, implementation status,
usage instructions, and interpretation guide.
_Last updated: 2026-03-02_
---
## Metric Summary
| Metric | Category | Status | Location | Trust |
|--------|----------|--------|----------|-------|
| **FVD** | Distribution | ✅ Implemented | `benchmarks/fvd/` | High |
| **SSIM** | Reference | ✅ Implemented | `fastvideo/tests/ssim/` | High |
| **LPIPS** | Perceptual | ✅ Implemented | `scripts/lora_extraction/` | Medium |
| **Loss trajectory** | Training signal | ✅ Implemented | W&B `train_loss` | Medium |
| **Grad norm stability** | Training signal | ✅ Implemented | W&B `grad_norm` | Medium |
| **GameWorld Score** | Multi-dim benchmark | 🟡 External | Matrix-Game repo | Low |
| **Human preference** | Gold standard | 🔴 Manual | N/A | Highest |
---
## Implemented Metrics
### FVD — Fréchet Video Distance
**Category**: Distribution-level quality metric
**Status**: ✅ Fully implemented in `benchmarks/fvd/`
**Trust**: High — standard protocol, I3D feature extractor
#### What It Measures
FVD measures the distance between the **distribution** of generated videos and
a distribution of real/reference videos. It works by:
1. Extracting spatiotemporal features from both real and generated video sets
using a pretrained **I3D** (Inflated 3D ConvNet) model.
2. Modeling each set of features as a multivariate Gaussian (mean + covariance).
3. Computing the **Fréchet distance** between the two Gaussians.
Lower FVD = generated videos are more statistically similar to real videos.
#### Why It Matters
- FVD is the **de facto standard** for benchmarking video generation models.
- It captures both **visual quality** (are individual frames realistic?) and
**temporal coherence** (do frames flow naturally?).
- Matrix-Game 2.0, Open-Sora, and most video generation papers report FVD.
#### Limitations
- Requires a **large sample set** (standard protocol uses 2048 videos) to
produce stable statistics. Small sample sizes yield noisy results.
- Measures **distributional similarity**, not per-video quality. A model could
have low FVD by generating a diverse set of "roughly okay" videos.
- The I3D model was trained on Kinetics-400 (human actions). It may be less
sensitive to domain-specific artifacts in non-human-action videos (e.g.,
driving, game environments).
- Does not directly measure text-video alignment or action controllability.
#### How to Use
```python
# Programmatic
from benchmarks.fvd import compute_fvd_with_config, FVDConfig
config = FVDConfig.fvd2048_16f() # Standard: 2048 videos, 16 frames
results = compute_fvd_with_config('data/real/', 'outputs/gen/', config)
print(f"FVD: {results['fvd']:.2f}")
```
```bash
# CLI
python -m benchmarks.fvd.cli \
--real-path data/real/ \
--gen-path outputs/gen/ \
--protocol fvd2048_16f
```
**Preset protocols**:
| Protocol | Videos | Frames | Use Case |
|----------|--------|--------|----------|
| `fvd2048_16f` | 2048 | 16 | Standard benchmark (papers) |
| `fvd2048_128f` | 2048 | 128 | Long video evaluation |
| `quick_test` | 100 | 16 | Fast dev iteration |
**Feature extractors**: `i3d` (default, standard), `clip`, `videomae`
#### Interpretation
| FVD Range | Interpretation |
|-----------|---------------|
| < 100 | Excellent — near-real quality |
| 100–300 | Good — competitive with SOTA |
| 300–600 | Fair — noticeable gap from real |
| > 600 | Poor — significant quality issues |
> FVD values are dataset-dependent. Always compare against baselines evaluated
> on the same real video distribution.
---
### SSIM — Structural Similarity Index
**Category**: Per-frame reference comparison
**Status**: ✅ Implemented in `fastvideo/tests/ssim/`
**Trust**: High — used in CI regression tests
#### What It Measures
SSIM compares two images (or video frames) based on three components:
1. **Luminance**: brightness similarity
2. **Contrast**: dynamic range similarity
3. **Structure**: spatial pattern similarity
The final score is a value in [0, 1] where 1.0 = identical.
#### Why It Matters
- Used as a **regression guard** in CI: ensures model updates don't degrade
visual output below a threshold.
- More perceptually meaningful than raw pixel MSE.
- Fast to compute — suitable for automated testing.
#### Limitations
- Requires a **pixel-aligned reference** video. Cannot compare videos with
different seeds, prompts, or angles.
- Operates **per-frame** — does not capture temporal coherence.
- Insensitive to some perceptual artifacts (color shifts, high-frequency noise).
#### How to Use
```bash
pytest fastvideo/tests/ssim/ -vs
```
#### Interpretation
| SSIM Range | Quality |
|------------|---------|
| > 0.90 | Excellent — very close to reference |
| 0.80–0.90 | Good — acceptable for most uses |
| 0.70–0.80 | Fair — noticeable differences |
| < 0.70 | Poor — significant divergence |
---
### LPIPS — Learned Perceptual Image Patch Similarity
**Category**: Per-frame perceptual distance
**Status**: ✅ Implemented in `scripts/lora_extraction/lora_inference_comparison.py`
**Trust**: Medium — available but only used for LoRA comparison currently
#### What It Measures
LPIPS uses a pretrained neural network (AlexNet by default) to extract
deep features from two images and computes the distance between them in
feature space. Unlike SSIM, LPIPS correlates much more strongly with
**human perceptual judgments**.
Lower LPIPS = more perceptually similar.
#### Why It Matters
- Best available automated proxy for **human visual judgments** at the frame
level.
- Captures semantic and structural differences that SSIM misses (e.g., texture
changes, minor recoloring).
- Used for validating LoRA merge quality.
#### Limitations
- Per-frame metric — no temporal awareness.
- Requires reference video (paired comparison only).
- Slightly slower than SSIM due to neural network forward pass.
#### How to Use
```bash
python scripts/lora_extraction/lora_inference_comparison.py \
--base merged_model \
--ft path/to/finetuned \
--adapter NONE \
--output-dir results \
--prompt "A cat" \
--compute-lpips
```
#### Interpretation
| LPIPS Range | Quality |
|-------------|---------|
| < 0.10 | Excellent — nearly indistinguishable |
| 0.10–0.20 | Good — minor perceptual differences |
| 0.20–0.40 | Fair — noticeable differences |
| > 0.40 | Poor — clearly different |
---
### Loss Trajectory
**Category**: Training signal proxy
**Status**: ✅ Active (from W&B `train_loss`)
**Trust**: Medium — proxy, not direct quality measure
#### What It Measures
Tracks the training loss over time. A healthy training run shows:
- **Decreasing loss** over the first hundreds of steps.
- **Stable gradient norms** (no wild spikes).
- **Consistent step times** (no infrastructure issues).
#### Why It Matters
- Cheapest evaluation signal — available in real-time from W&B.
- Critical for the **30-minute quality check** workflow.
- At later training stages (when loss becomes meaningful), trajectory shape
can predict final model quality.
#### Context: How This Evolves
The team's experience shows evaluation signals change during a project:
- **Early stage**: Loss may be flat or meaningless → focus on SSIM & visual
inspection instead.
- **Mid stage**: Loss starts decreasing → trajectory shape becomes useful.
- **Late stage**: Loss is meaningful → can compare trajectories across runs.
This dynamic is a key insight from the team's workflow: don't over-rely on
loss early; don't ignore it late.
---
### Grad Norm Stability
**Category**: Training health diagnostic
**Status**: ✅ Active (from W&B `grad_norm`)
**Trust**: Medium — diagnostic, not quality metric
#### What It Measures
The magnitude of gradients during training. Stable grad norms indicate
healthy optimization. Spikes or NaN values indicate training instability.
#### Alert Thresholds
| Condition | Meaning |
|-----------|---------|
| Stable ~0.3–0.5 | Normal training |
| Single spike > 3× average | Possible bad batch, monitor |
| NaN or Inf | 🔴 Training has diverged — stop run |
| Increasing trend | Learning rate may be too high |
---
## External Benchmarks
### GameWorld Score Benchmark (Matrix-Game)
**Category**: Multi-dimensional evaluation framework for interactive world models
**Status**: 🟡 External — not implemented in-repo
**Source**: [Matrix-Game 1.0 benchmark](https://github.com/SkyworkAI/Matrix-Game), used in [Matrix-Game 2.0 paper](https://arxiv.org/abs/2508.13009)
#### What It Measures
A comprehensive benchmark examining **four critical capabilities**:
| Dimension | What It Evaluates | Example Signals |
|-----------|-------------------|-----------------|
| **Visual quality** | Frame-level realism, absence of artifacts | Color fidelity, sharpness, coherence |
| **Temporal quality** | Smoothness across frames, motion consistency | Jitter, flickering, temporal aliasing |
| **Action controllability** | Response to input actions (keyboard/mouse) | Action delay, correctness, smoothness |
| **Physical rule understanding** | Adherence to physics (gravity, collision) | Object persistence, plausible motion |
#### Context from Matrix-Game 2.0
- Evaluation uses **597-frame composite action sequences** over 32 Minecraft
scenes and 16 wild scenes.
- Action controllability assessment is **Minecraft-specific** — cannot be
directly applied to wild/general scenes.
- The paper notes that models that "collapse" to static frames can
paradoxically score higher on consistency metrics — beware of this confound.
#### Relevance to FastVideo
- Matrix-Game 2.0 is built on SkyReels-V2/Wan2.1 architecture — **same model
family as FastVideo**.
- Their distillation uses DMD-based Self-Forcing — **same technique** as our
`self_forcing_distillation_pipeline.py`.
- GameWorld Score dimensions are a useful framework for thinking about world
model quality even outside gaming contexts.
---
## Human Preference Evaluation
**Category**: Gold-standard quality assessment
**Status**: 🔴 Manual process — no automated implementation
**Priority**: **Highest** — this is the most important evaluation signal
**Trust**: Highest — but expensive
### What It Measures
Human evaluators compare generated videos and rate them on dimensions like:
- Overall quality and realism
- Temporal coherence and smoothness
- Prompt adherence / action correctness
- Absence of artifacts
#### Why It's the Most Important Metric
All automated metrics are **proxies** for human judgment. They can be gamed
or may miss artifacts that humans easily notice. Human preference is the
ultimate ground truth for video generation quality.
#### Cost & Practicality
| Approach | Cost | Scale | When to Use |
|----------|------|-------|-------------|
| Internal team review | Low | ~10–50 videos | Every major checkpoint |
| Crowdsource (MTurk, Scale) | Medium | 100+ videos | Pre-release validation |
| A/B preference test | Medium | Pairs | Comparing two model versions |
#### Recommended Protocol
1. Sample 10–20 videos from the model at a checkpoint.
2. Include diverse prompts (easy + hard, short + long).
3. Have 2–3 evaluators score each video 1–5 on: quality, coherence, fidelity.
4. Record scores in the experiment journal.
---
## Metrics NOT Used
| Metric | Reason |
|--------|--------|
| ~~CLIP-Score~~ | Not used by the team. Measures text-image alignment using CLIP embeddings, but not well-suited for video temporal quality. |
| Inception Score (IS) | Less informative than FVD for video; primarily an image metric. |
| PSNR | Pixel-level metric; less perceptually meaningful than SSIM/LPIPS. |
---
## Adding a New Metric
Follow the SOP: `.agents/workflows/evaluation-development.md`
1. Prototype in `.agents/exploration/`
2. Validate on known-good and known-bad samples
3. Add to this registry
4. Update the `evaluate-video-quality` skill
@@ -1,21 +0,0 @@
# Experiment Journal
Living log of all experiments. Each entry captures what was tried, the result,
and any insights. Newest entries go at the top.
_No experiments logged yet. Use the `log-experiment` skill to add entries._
<!-- TEMPLATE — copy and fill for each new experiment:
## [YYYY-MM-DD] Experiment: <name>
- **Hypothesis**: <what you expected to learn>
- **Config**: model=..., lr=..., sp_size=..., gpus=..., script=...
- **W&B run**: <run_id or URL>
- **Duration**: <total wall time>
- **Key metrics**: loss=..., step_time=..., grad_norm=...
- **Checkpoint**: <path>
- **Insight**: <what was learned>
- **Status**: running | completed | failed | abandoned
- **Related lessons**: `.agents/lessons/<filename>.md`
-->
-5
View File
@@ -1,5 +0,0 @@
{"name": "codebase-map", "description": "High-level structural index of the FastVideo-WorldModel repository", "path": "codebase-map/README.md", "status": "ready", "trust": "high"}
{"name": "evaluation-registry", "description": "Catalog of all evaluation metrics with detailed explanations, implementation status, and usage guides", "path": "evaluation-registry/README.md", "status": "draft", "trust": "medium"}
{"name": "experiment-journal", "description": "Living log of all experiments with hypotheses, configs, metrics, and insights", "path": "experiment-journal/README.md", "status": "draft", "trust": "medium"}
{"name": "related-work", "description": "Index of related papers, repos, and blog posts with structured comparisons to FastVideo", "path": "related-work/README.md", "status": "draft", "trust": "low"}
{"name": "dreamverse-integration", "description": "Consolidated knowledge base for the FastVideo public API refactor (PRs 0-17), LTX-2 streaming server upstream, Dreamverse migration from FastVideo-internal, and NVFP4 quantization landing", "path": "dreamverse-integration/README.md", "status": "ready", "trust": "high"}
-34
View File
@@ -1,34 +0,0 @@
# Related Work Index
Each file in this directory is a structured summary of a related paper, repo,
or blog post relevant to FastVideo-WorldModel training.
## File Format
Each file is named `<slug>.md` and follows this structure:
```markdown
---
title: <paper/repo title>
source: <URL or citation>
type: paper | repo | blog
date_indexed: <ISO-8601>
tags: [world-model, distillation, evaluation, reward-shaping, ...]
---
## Summary
<1-2 paragraph summary of the work.>
## Key Differences from FastVideo
- <Bullet points comparing their approach to ours.>
## Actionable Insights
- <What we could adopt or adapt.>
```
## How to Add New Entries
Use the `index-related-work` skill, or manually create a file following the
template above.
_No related work indexed yet._
-76
View File
@@ -1,76 +0,0 @@
# Agent Onboarding — FastVideo-WorldModel
Welcome, agent. This is the **master onboarding** guide. Follow the steps below,
then check if a **domain-specific onboarding** exists for your task.
## Domain-Specific Onboarding
If your task falls into one of these areas, read the specialized guide **after**
completing the general steps below:
| Domain | Guide | When to Use |
|--------|-------|-------------|
| **WorldModel Training** | `worldmodel-training/README.md` | Training, finetuning, distillation, experiment management |
---
## Step 1: Understand the Codebase
Read these files to build your context:
| Priority | File | What you learn |
|----------|------|----------------|
| 1 | `AGENTS.md` | Coding guidelines, build/test commands, PR conventions |
| 2 | `docs/design/overview.md` | Architecture: models, pipelines, configs, registry |
| 3 | `fastvideo/train/` | Refactored training framework (YAML-driven, modular methods/models/callbacks) |
| 4 | `docs/training/overview.md` | Training data flow and preprocessing |
| 5 | `docs/training/finetune.md` | Training arguments, parallelism, LoRA, validation |
| 6 | `docs/contributing/coding_agents.md` | How to add model pipelines with agent assistance |
## Step 2: Discover Available Resources
Read these two index files to see what skills and memory modules exist:
- **`.agents/skills/index.jsonl`** — catalog of all agent skills (name + description)
- **`.agents/memory/index.jsonl`** — catalog of all memory modules (name + description)
Each entry has a `path` field pointing to the full content. Only load the
full README.md for modules relevant to your current task.
## Step 3: Check for Existing Skills & SOPs
Before writing new code or procedures:
1. **Skills**: Read `.agents/skills/index.jsonl` — find a matching skill by description.
2. **Workflows/SOPs**: Browse `.agents/workflows/` — step-by-step procedures for common tasks.
3. **Lessons**: Browse `.agents/lessons/` — known pitfalls and their fixes.
If a skill or SOP exists for your task, **use it**. If not, you are in **exploration mode** — see Step 4.
## Step 4: Exploration Mode
If no existing skill/SOP covers your task:
1. Document your progress in `.agents/exploration/<topic>.md` using the template in `.agents/exploration/README.md`.
2. At the end of your session, reflect:
- **What worked** → propose a new skill or SOP in the exploration log.
- **What failed** → create a lesson in `.agents/lessons/`.
3. Flag the exploration log for human review.
## Quick Reference
```
.agents/
├── ONBOARDING.md ← you are here
├── STATUS.md ← dashboard: completeness & trust of all components
├── skills/ ← reusable agent skills
├── workflows/ ← SOPs and procedures
├── memory/ ← persistent context (folder per topic + index.jsonl)
│ ├── index.jsonl
│ ├── codebase-map/
│ ├── experiment-journal/
│ ├── evaluation-registry/
│ └── related-work/
├── lessons/ ← mistakes and fixes
└── exploration/ ← draft procedures
```
@@ -1,302 +0,0 @@
# WorldModel Training — Agent Onboarding
Specialized onboarding for agents working on FastVideo-WorldModel training,
distillation, and evaluation. Read the master onboarding (`.agents/onboarding/README.md`)
first, then come here.
---
## Domain Context
FastVideo-WorldModel trains **interactive world models** — video generation systems
that respond to user actions (keyboard/mouse) in real-time. The architecture is
based on **Wan2.1** (SkyReels-V2) DiT models with causal attention for
auto-regressive streaming generation.
**Key techniques you will work with:**
- Full finetuning and LoRA on Wan / LTX-2 / MatrixGame models
- DMD-based distillation (few-step generation)
- Self-Forcing distillation (causal streaming)
- Diffusion-Forcing SFT (DFSFT) for causal models
- VSA (Variable Sparsity Acceleration) for efficient training
---
## Training Code: Two Generations
### New modular framework: `fastvideo/train/` (preferred)
The refactored training code uses a **YAML-only config-driven** architecture
with composable methods, per-role models, and a callback system. All new
training work should use this framework.
### Legacy pipelines: `fastvideo/training/` (deprecated)
The old monolithic pipeline classes (`WanTrainingPipeline`,
`DistillationPipeline`, etc.) still exist but are being phased out. The new
framework imports select utilities from `fastvideo/training/` for backward
compatibility (EMA, gradient clipping, checkpoint wrappers).
---
## Essential Reading (Training-Specific)
Read these **in order** before touching any training code:
| # | File | What You Learn |
|---|------|----------------|
| 1 | `docs/training/overview.md` | Training data flow: raw video → text embeddings + video latents → training |
| 2 | `docs/training/finetune.md` | Training arguments, parallelism (SP/TP), LoRA, validation settings |
| 3 | `docs/training/data_preprocess.md` | How to preprocess datasets into the expected format |
| 4 | `docs/design/overview.md` | Architecture: models, pipelines, configs, registry |
---
## New Training Framework (`fastvideo/train/`)
### Architecture Overview
```
fastvideo/train/
├── __init__.py → exports Trainer
├── trainer.py → main training loop coordinator
├── entrypoint/
│ ├── train.py → YAML-only training entrypoint
│ └── dcp_to_diffusers.py → checkpoint conversion utility
├── methods/ → training algorithms (TrainingMethod ABC)
│ ├── base.py → TrainingMethod base class
│ ├── fine_tuning/
│ │ ├── finetune.py → FineTuneMethod (supervised finetuning)
│ │ └── dfsft.py → DiffusionForcingSFTMethod (causal)
│ ├── distribution_matching/
│ │ ├── dmd2.py → DMD2Method (distribution matching distill)
│ │ └── self_forcing.py → SelfForcingMethod (causal streaming)
│ ├── knowledge_distillation/ → (stub, not yet implemented)
│ └── consistency_model/ → (stub, not yet implemented)
├── models/ → per-role model instances
│ ├── base.py → ModelBase & CausalModelBase (ABC)
│ └── wan/
│ ├── wan.py → WanModel (non-causal)
│ └── wan_causal.py → WanCausalModel (causal streaming)
├── callbacks/ → training hooks & monitoring
│ ├── callback.py → Callback base class + CallbackDict
│ ├── grad_clip.py → GradNormClipCallback
│ ├── ema.py → EMACallback (shadow weights)
│ └── validation.py → ValidationCallback (sampling + eval)
└── utils/ → configuration, building, checkpointing
├── builder.py → build_from_config() (config → runtime)
├── checkpoint.py → CheckpointManager (DCP-based)
├── config.py → load_run_config() (YAML → RunConfig)
├── training_config.py → TypedConfig dataclasses
├── optimizer.py → build_optimizer_and_scheduler()
├── instantiate.py → resolve_target() + instantiate()
├── tracking.py → build_tracker() (W&B, etc.)
├── dataloader.py → dataloader utilities
├── module_state.py → apply_trainable()
└── moduleloader.py → load_module_from_path()
```
### Key Concepts
**TrainingMethod** (`methods/base.py`): Abstract base class for all training
algorithms. Owns role models (student, teacher, critic), manages checkpoint
state, and defines the training step interface.
**ModelBase** (`models/base.py`): Per-role model wrapper. Each role (student,
teacher, critic) gets its own `ModelBase` instance owning a `transformer` and
`noise_scheduler`. `CausalModelBase` extends this for streaming models.
**Callback system** (`callbacks/`): Composable hooks for gradient clipping,
EMA, validation, etc. Configured via YAML, dispatched by `CallbackDict`.
**Config system** (`utils/config.py`, `utils/training_config.py`): YAML files
are parsed into typed `RunConfig` dataclass trees. Models and methods use
`_target_` fields for instantiation (similar to Hydra).
### Training Flow
```
run_training_from_config(config_path)
→ load_run_config() # YAML → RunConfig
→ init_distributed() # TP/SP setup
→ build_from_config() # instantiate models, method, dataloader
→ Trainer.run() # main loop:
├─ callbacks.on_train_start()
├─ checkpoint_manager.maybe_resume()
├─ for step in range(max_steps):
│ ├─ method.single_train_step(batch)
│ ├─ method.backward()
│ ├─ callbacks.on_before_optimizer_step()
│ ├─ method.optimizers_schedulers_step()
│ ├─ tracker.log(metrics, step)
│ ├─ callbacks.on_training_step_end()
│ └─ checkpoint_manager.maybe_save(step)
├─ callbacks.on_train_end()
└─ checkpoint_manager.save_final()
```
### Training Methods
| Method | Class | Use Case |
|--------|-------|----------|
| **FineTune** | `FineTuneMethod` | Single-role supervised finetuning |
| **DFSFT** | `DiffusionForcingSFTMethod` | Diffusion-forcing SFT with inhomogeneous timesteps |
| **DMD2** | `DMD2Method` | Multi-role distribution matching distillation (student + teacher + critic) |
| **Self-Forcing** | `SelfForcingMethod` | Extends DMD2 for causal student rollouts |
### Launching Training (New Framework)
Training is launched via `torchrun` with a single YAML config:
```bash
torchrun --nproc_per_node <N_GPUS> \
-m fastvideo.train.entrypoint.train \
--config examples/train/<config>.yaml
```
### Example YAML Configs
| Config | Method | Description |
|--------|--------|-------------|
| `examples/train/finetune_wan2.1_t2v_1.3B_vsa_phase3.4_0.9sparsity.yaml` | FineTune | Wan 1.3B finetuning with VSA sparsity |
| `examples/train/distill_wan2.1_t2v_1.3B_dmd2.yaml` | DMD2 | Wan 1.3B distillation (student + teacher + critic) |
| `examples/train/dfsft_wan_causal_t2v_1.3B.yaml` | DFSFT | Causal Wan 1.3B diffusion-forcing SFT |
| `examples/train/self_forcing_wan_causal_t2v_1.3B.yaml` | Self-Forcing | Causal streaming distillation |
### Checkpointing (New Framework)
**CheckpointManager** (`utils/checkpoint.py`) saves via `torch.distributed.checkpoint`:
```
output_dir/
└─ checkpoint-{step}/
├─ dcp/ # DCP state dict
├─ config.json # resolved training config
└─ .fastvideo_metadata.json
```
Checkpoint state includes: role model weights, per-role optimizers/schedulers,
CUDA RNG state, and callback state (e.g., EMA shadow weights).
### Config Structure
A YAML config defines the full training pipeline:
```yaml
models:
student:
_target_: fastvideo.train.models.wan.WanModel
model_path: ...
trainable: true
teacher: # optional, for distillation
_target_: fastvideo.train.models.wan.WanModel
model_path: ...
trainable: false
method:
_target_: fastvideo.train.methods.fine_tuning.FineTuneMethod
# method-specific params...
training:
distributed: { num_gpus: 8, tp_size: 1, sp_size: 8 }
data: { data_path: ..., batch_size: 1 }
optimizer: { lr: 1e-5, lr_scheduler: constant_with_warmup }
loop: { max_train_steps: 1000 }
checkpoint: { output_dir: ./outputs }
tracker: { trackers: [wandb], project_name: ... }
callbacks:
grad_clip:
_target_: fastvideo.train.callbacks.GradNormClipCallback
max_grad_norm: 1.0
validation:
_target_: fastvideo.train.callbacks.ValidationCallback
validation_steps: 100
```
---
## Legacy Training Pipelines (`fastvideo/training/`)
> **Note:** Use the new `fastvideo/train/` framework for new work. This section
> is retained for reference on existing pipelines not yet migrated.
| Pipeline | Entrypoint | Use Case |
|----------|-----------|----------|
| Wan T2V finetune | `fastvideo/training/wan_training_pipeline.py` | Standard text-to-video finetune / LoRA |
| Wan I2V finetune | `fastvideo/training/wan_i2v_training_pipeline.py` | Image-to-video (first frame conditioned) |
| MatrixGame finetune | `fastvideo/training/matrixgame_training_pipeline.py` | Action-conditioned world model |
| LTX-2 finetune | `fastvideo/training/ltx2_training_pipeline.py` | LTX-2 architecture finetuning |
| Wan DMD distillation | `fastvideo/training/wan_distillation_pipeline.py` | Few-step distillation via DMD |
| Self-Forcing distill | `fastvideo/training/wan_self_forcing_distillation_pipeline.py` | Causal streaming distillation |
---
## Key Infrastructure
### W&B Integration
- **Tracker**: `fastvideo/training/trackers.py` — `WandbTracker` class
- **New framework tracker**: `fastvideo/train/utils/tracking.py` — `build_tracker()`
- **Env vars**: `WANDB_API_KEY`, `WANDB_BASE_URL`, `WANDB_MODE`
### Parallelism
- **SP** (Sequence Parallel): splits video frames across GPUs — `sp_size: N`
- **TP** (Tensor Parallel): splits model layers across GPUs — `tp_size: N`
- Typical configs: SP=2–8, TP=1–2
---
## Evaluation (for training runs)
Read `.agents/memory/evaluation-registry/README.md` for the full metric catalog.
**Quick summary for training agents:**
| Metric | When to Use | Trust |
|--------|-------------|-------|
| **Loss trajectory** | Every run, real-time from W&B | Medium |
| **SSIM** | When comparing against reference outputs | High |
| **FVD** | For benchmarking model quality (`benchmarks/fvd/`) | High |
| **LPIPS** | LoRA merge validation | Medium |
| **Human preference** | Major checkpoints | Highest |
---
## Common Workflows
| Task | Skill / SOP |
|------|-------------|
| Launch a training run | `.agents/skills/launch-experiment/SKILL.md` |
| Monitor a running experiment | `.agents/skills/monitor-experiment/SKILL.md` |
| Summarize final results | `.agents/skills/summarize-run/SKILL.md` |
| Full experiment lifecycle | `.agents/workflows/experiment-lifecycle.md` |
| Capture lessons from failures | `.agents/workflows/lesson-capture.md` |
---
## World Model–Specific Concepts
### Action Injection (MatrixGame)
The MatrixGame pipeline adds **action modules** to each DiT block, enabling
frame-level mouse/keyboard input conditioning. The action sequence is injected
per-frame alongside the latent video tokens.
### Causal Architecture
For streaming generation, the model uses **causal attention** (each frame only
attends to previous frames). This enables auto-regressive chunk-by-chunk
generation — critical for real-time interactive world models.
### Self-Forcing Distillation
A **data-free** distillation method where the student model is trained to
generate coherent video sequences by being forced to use its own previous
outputs (rather than ground-truth) as context. This produces models robust to
their own error accumulation during long auto-regressive generation.
### DMD Distillation (Distribution Matching Distillation)
Reduces inference steps from ~50 to 3–4 by training a student model to match
the output distribution of the teacher model. Uses a critic network to estimate
distribution divergence.
### Diffusion-Forcing SFT (DFSFT)
Supervised finetuning with **inhomogeneous timesteps** across chunks — each
chunk in a causal sequence can have a different noise level, training the model
to handle mixed-fidelity contexts.
-96
View File
@@ -1,96 +0,0 @@
#!/usr/bin/env bash
# Sync .agents/skills/ into .claude/skills/ via per-skill symlinks.
#
# Why: Claude Code only scans .claude/skills/ and ~/.claude/skills/ for
# user-invocable skills (no skillsPath config exists — see
# https://code.claude.com/docs/en/skills.md). This repo's skills live
# in .agents/skills/ so they travel with the repo and stay under git.
# Run this once after cloning (or after adding/removing a skill) to
# expose them to Claude Code without maintaining a parallel tree.
#
# Usage:
# .agents/scripts/sync-skills.sh
#
# Idempotent and safe to re-run. Prunes stale symlinks whose source
# has been removed from .agents/skills/. Leaves hand-written
# .claude/skills/<name>/ directories untouched (only symlinks are
# managed).
set -euo pipefail
REPO_ROOT="$(git -C "$(dirname "$0")" rev-parse --show-toplevel)"
SRC_DIR="$REPO_ROOT/.agents/skills"
DST_DIR="$REPO_ROOT/.claude/skills"
if [[ ! -d "$SRC_DIR" ]]; then
echo "Error: $SRC_DIR does not exist." >&2
exit 1
fi
mkdir -p "$DST_DIR"
linked=0
unchanged=0
skipped=0
pruned=0
link_skill() {
local name="$1"
local src="$SRC_DIR/$name"
local dst="$DST_DIR/$name"
# Relative target keeps symlinks portable across clones.
local rel="../../.agents/skills/$name"
if [[ -L "$dst" ]]; then
if [[ "$(readlink "$dst")" == "$rel" ]]; then
unchanged=$((unchanged + 1))
return
fi
rm "$dst"
elif [[ -e "$dst" ]]; then
echo "Skipped (not a symlink): .claude/skills/$name" >&2
skipped=$((skipped + 1))
return
fi
ln -s "$rel" "$dst"
echo "Linked: .claude/skills/$name -> $rel"
linked=$((linked + 1))
}
prune_stale() {
local link="$1"
local target
target="$(readlink "$link")"
case "$target" in
../../.agents/skills/*) ;;
*) return ;;
esac
local name="${target##*/}"
if [[ ! -d "$SRC_DIR/$name" ]]; then
rm "$link"
echo "Pruned stale: .claude/skills/$(basename "$link")"
pruned=$((pruned + 1))
fi
}
for src in "$SRC_DIR"/*/; do
[[ -d "$src" ]] || continue
name="$(basename "$src")"
# Only treat directories that actually contain a SKILL.md as skills.
[[ -f "$src/SKILL.md" ]] || continue
link_skill "$name"
done
shopt -s nullglob
for link in "$DST_DIR"/*; do
[[ -L "$link" ]] || continue
prune_stale "$link"
done
shopt -u nullglob
printf "\nSummary: %d linked, %d unchanged, %d pruned" "$linked" "$unchanged" "$pruned"
if [[ "$skipped" -gt 0 ]]; then
printf ", %d skipped (non-symlink collision)" "$skipped"
fi
printf "\n"
-57
View File
@@ -1,57 +0,0 @@
---
name: <skill-name>
description: <one-line description — Codex uses this for implicit invocation matching>
---
# <Skill Name>
## Purpose
<Why this skill exists and when to use it.>
## Prerequisites
- <What must be true before using this skill>
## Inputs
| Parameter | Required | Description |
|-----------|----------|-------------|
| `param1` | Yes | ... |
## Steps
1. **Step 1 title**
- Detail...
2. **Step 2 title**
- Detail...
## Outputs
- <What this skill produces>
## Example Usage
```
<Example invocation or prompt snippet>
```
## References
- <Links to relevant files in the codebase>
---
## Folder Structure
Each skill lives in its own directory under `.agents/skills/`:
```
.agents/skills/<skill-name>/
├── SKILL.md # Required: instructions + metadata (this file)
├── scripts/ # Optional: executable helper scripts
├── references/ # Optional: documentation, papers
└── assets/ # Optional: templates, resources
```
After creating a new skill, add an entry to `.agents/skills/index.jsonl`:
```json
{"name": "<skill-name>", "description": "<description>", "path": "<skill-name>/SKILL.md", "status": "draft", "trust": "low"}
```
@@ -1,128 +0,0 @@
---
name: evaluate-video-quality
description: Evaluate generated video quality using available metrics (SSIM, loss trajectory, caption consistency)
---
# Evaluate Video Quality
## Purpose
Assess the quality of videos generated by a training run. Combines multiple
signals to give a holistic quality assessment. This skill is **evolving** —
new metrics will be added as they are developed.
## Prerequisites
- Generated videos available locally or via W&B artifacts.
- For SSIM: reference videos from official implementations.
- For caption consistency: LLM access (optional, stub for now).
## Inputs
| Parameter | Required | Description |
|-----------|----------|-------------|
| `video_paths` | Yes | List of paths to generated videos |
| `reference_paths` | No | Paths to reference videos (for SSIM) |
| `prompts` | No | Prompts used to generate videos (for caption check) |
| `loss_summary` | No | Path to W&B summary JSON (for loss trajectory) |
| `metrics` | No | Which metrics to run (default: all available) |
## Available Metrics
Check `.agents/memory/evaluation-registry/README.md` for the current catalog.
### SSIM (Active)
Leverages the existing infrastructure in `fastvideo/tests/ssim/`.
```bash
pytest fastvideo/tests/ssim/ -vs --video-path <generated> --reference-path <reference>
```
Or use the SSIM utility directly:
```python
from fastvideo.tests.ssim.ssim_utils import compute_ssim
score = compute_ssim(generated_video, reference_video)
# score > 0.85 is typically "acceptable"
```
**Interpretation**:
| SSIM Range | Quality |
|------------|---------|
| > 0.90 | Excellent — very close to reference |
| 0.80–0.90 | Good — acceptable for most uses |
| 0.70–0.80 | Fair — noticeable differences |
| < 0.70 | Poor — significant quality issues |
### Loss Trajectory (Active)
Analyze the loss curve shape from W&B summary:
```python
import json
with open(loss_summary_path) as f:
summary = json.load(f)
final_loss = summary["train_loss"]
runtime = summary["_runtime"]
steps = summary["_step"]
```
**Early-stage heuristics** (first 500 steps):
- Loss should be decreasing (even slightly).
- Grad norm should be stable (no wild oscillations).
- If loss is flat or increasing, flag for review.
### Caption Consistency (Draft — Not Yet Calibrated)
Use an LLM to evaluate whether the video content matches the input prompt.
```
Prompt: "A golden retriever playing in the snow"
Video: <path>
Score the video on:
1. Object presence (is there a golden retriever?)
2. Action accuracy (is it playing?)
3. Environment match (is there snow?)
4. Overall coherence (does it look natural?)
Each 1-5, total /20.
```
> ⚠️ This metric is in **draft** status. Results should not be treated as
> ground truth until calibrated against human judgments.
## Steps
1. **Identify available metrics** — Check `.agents/memory/evaluation-registry/README.md`.
2. **Run each metric** — Collect scores.
3. **Aggregate** — Produce a combined quality report.
4. **Log** — Update the experiment journal with quality results.
## Outputs
```markdown
## Video Quality Report: <experiment_name>
| Metric | Score | Threshold | Status |
|--------|-------|-----------|--------|
| SSIM (avg) | 0.87 | > 0.80 | ✅ Pass |
| Loss trajectory | decreasing | decreasing | ✅ Pass |
| Caption consistency | 16/20 | > 14/20 | ✅ Pass |
### Per-Video Scores
| Video | SSIM | Caption |
|-------|------|---------|
| video_001.mp4 | 0.89 | 17/20 |
| video_002.mp4 | 0.85 | 15/20 |
```
## References
- `fastvideo/tests/ssim/` — SSIM test infrastructure
- `fastvideo/tests/training/Vanilla/test_training_loss.py` — loss comparison
- `.agents/memory/evaluation-registry/README.md` — metric catalog
## Changelog
| Date | Change |
|------|--------|
| 2026-03-02 | Initial version with SSIM, loss trajectory, caption consistency stub |
-7
View File
@@ -1,7 +0,0 @@
{"name": "launch-experiment", "description": "Generate and execute a training launch command for FastVideo models", "path": "launch-experiment/SKILL.md", "status": "draft", "trust": "low"}
{"name": "monitor-experiment", "description": "Poll a running W&B training run for progress and emit structured alerts", "path": "monitor-experiment/SKILL.md", "status": "draft", "trust": "low"}
{"name": "summarize-run", "description": "Extract a W&B run summary into a structured experiment report", "path": "summarize-run/SKILL.md", "status": "draft", "trust": "low"}
{"name": "log-experiment", "description": "Append or update an experiment entry in the experiment journal", "path": "log-experiment/SKILL.md", "status": "draft", "trust": "low"}
{"name": "evaluate-video-quality", "description": "Evaluate generated video quality using available metrics (SSIM, loss trajectory, caption consistency)", "path": "evaluate-video-quality/SKILL.md", "status": "draft", "trust": "low"}
{"name": "seed-ssim-references", "description": "Run a new or updated fastvideo/tests/ssim/ test on Modal, pull generated videos, and upload them to FastVideo/ssim-reference-videos so the test has a regression baseline", "path": "seed-ssim-references/SKILL.md", "status": "draft", "trust": "low"}
{"name": "reseed-ssim-references", "description": "Re-seed (overwrite) HF reference videos for an existing fastvideo/tests/ssim/ test and a single model id on Modal L40S. Always backs up current refs first, regenerates on Modal, pauses for the user to eyeball before-vs-after, then uploads with --force scoped to --model-id. Sister skill to seed-ssim-references; use when intentional code change has invalidated existing refs", "path": "reseed-ssim-references/SKILL.md", "status": "draft", "trust": "low"}
-127
View File
@@ -1,127 +0,0 @@
---
name: launch-experiment
description: Generate and execute a training launch command for FastVideo models
---
# Launch Experiment
## Purpose
Construct a fully-specified `torchrun` training command for a FastVideo model
given a target pipeline, dataset, and hyperparameter overrides. This skill
automates the boilerplate of setting environment variables, picking the right
entrypoint, and applying defaults from the closest example script.
## Prerequisites
- The repo is cloned and `fastvideo` is installed (`uv pip install -e ".[dev]"`).
- Dataset is preprocessed (see `docs/training/data_preprocess.md`).
- `WANDB_API_KEY` is set in the environment (or `WANDB_MODE=offline` for local).
- GPU resources are available (multi-GPU requires NCCL).
## Inputs
| Parameter | Required | Description |
|-----------|----------|-------------|
| `pipeline` | Yes | Training pipeline type: `finetune`, `distill-dmd`, `self-forcing`, `lora`, `consistency` |
| `model` | Yes | Model family: `wan-t2v-1.3B`, `wan-i2v-14B`, `ltx2`, `matrixgame` |
| `data_path` | Yes | Path to preprocessed dataset (parquet) |
| `num_gpus` | Yes | Number of GPUs |
| `overrides` | No | Dict of hyperparameter overrides (any CLI arg) |
| `output_dir` | No | Output directory (default: `outputs/<model>_<pipeline>`) |
| `run_name` | No | W&B run name (default: auto-generated) |
## Steps
### 1. Identify the training entrypoint
| Pipeline | Entrypoint |
|----------|-----------|
| `finetune` (Wan T2V) | `fastvideo/training/wan_training_pipeline.py` |
| `finetune` (Wan I2V) | `fastvideo/training/wan_i2v_training_pipeline.py` |
| `finetune` (LTX-2) | `fastvideo/training/ltx2_training_pipeline.py` |
| `finetune` (MatrixGame) | `fastvideo/training/matrixgame_training_pipeline.py` |
| `distill-dmd` | `fastvideo/training/wan_distillation_pipeline.py` |
| `self-forcing` | `fastvideo/training/wan_self_forcing_distillation_pipeline.py` |
### 2. Resolve default hyperparameters
Find the closest example script in `examples/training/` for the model:
| Model | Example Script Directory |
|-------|-------------------------|
| `wan-t2v-1.3B` | `examples/training/finetune/wan_t2v_1.3B/crush_smol/` |
| `wan-i2v-14B` | `examples/training/finetune/wan_i2v_14B_480p/crush_smol/` |
| `ltx2` | `examples/training/finetune/ltx2/` |
| `matrixgame` | `examples/training/finetune/MatrixGame2.0/` |
| `distill-dmd` | `scripts/distill/v1_distill_dmd_wan.sh` |
Read the script to extract default values for:
- `--learning_rate`, `--train_batch_size`, `--sp_size`, `--tp_size`
- `--num_latent_t`, `--num_height`, `--num_width`, `--num_frames`
- `--gradient_accumulation_steps`, `--max_train_steps`
- `--mixed_precision`, `--weight_decay`, `--max_grad_norm`
- `--validation_steps`, `--validation_sampling_steps`
### 3. Set environment variables
```bash
export WANDB_API_KEY="${WANDB_API_KEY}"
export WANDB_BASE_URL="https://api.wandb.ai"
export FASTVIDEO_ATTENTION_BACKEND=FLASH_ATTN
export TOKENIZERS_PARALLELISM=false
export TRITON_CACHE_DIR=/tmp/triton_cache
```
### 4. Construct the torchrun command
```bash
torchrun --nnodes 1 --nproc_per_node <num_gpus> \
<entrypoint> \
--pretrained_model_name_or_path <model_hf_id> \
--data_path "<data_path>" \
--output_dir "<output_dir>" \
--wandb_run_name "<run_name>" \
--tracker_project_name "<project_name>" \
--log_validation \
<...all hyperparameters...>
```
### 5. Log to experiment journal
After launching, append an entry to `.agents/memory/experiment-journal/README.md`:
```markdown
## [YYYY-MM-DD] Experiment: <run_name>
- **Hypothesis**: <user-provided or auto-generated>
- **Config**: model=<model>, lr=<lr>, sp_size=<sp>, gpus=<n>, script=<entrypoint>
- **W&B run**: <pending — will be updated by monitor skill>
- **Status**: running
```
## Outputs
- A ready-to-execute shell command.
- An experiment journal entry.
## Example Usage
```
Launch a Wan T2V 1.3B finetune on 4 GPUs with lr=5e-5 and max_train_steps=1000:
pipeline: finetune
model: wan-t2v-1.3B
data_path: data/crush_smol_preprocessed/
num_gpus: 4
overrides:
learning_rate: 5e-5
max_train_steps: 1000
```
## References
- `examples/training/finetune/wan_t2v_1.3B/crush_smol/finetune_t2v.sh`
- `scripts/distill/v1_distill_dmd_wan.sh`
- `docs/training/finetune.md` (training arguments table)
- `fastvideo/training/trackers.py` (tracker initialization)
## Changelog
| Date | Change |
|------|--------|
| 2026-03-02 | Initial version |
-87
View File
@@ -1,87 +0,0 @@
---
name: log-experiment
description: Append or update an experiment entry in the experiment journal
---
# Log Experiment
## Purpose
Create or update an entry in `.agents/memory/experiment-journal/README.md` to maintain
a living record of all experiments and their outcomes.
## Prerequisites
- `.agents/memory/experiment-journal/README.md` exists.
## Inputs
| Parameter | Required | Description |
|-----------|----------|-------------|
| `name` | Yes | Experiment name / identifier |
| `hypothesis` | No | What you expected to learn |
| `config` | Yes | Key config: model, lr, sp_size, gpus, script |
| `wandb_run` | No | W&B run ID or URL |
| `duration` | No | Total wall time |
| `metrics` | No | Key metrics dict (loss, step_time, grad_norm) |
| `checkpoint` | No | Path to checkpoint |
| `insight` | No | What was learned |
| `status` | Yes | `running`, `completed`, `failed`, `abandoned` |
| `lessons` | No | Paths to related lesson files |
## Steps
### 1. Check for existing entry
Search `.agents/memory/experiment-journal/README.md` for an entry with the same name.
If found, update it instead of creating a duplicate.
### 2. Format the entry
```markdown
## [YYYY-MM-DD] Experiment: <name>
- **Hypothesis**: <hypothesis or "N/A">
- **Config**: model=<model>, lr=<lr>, sp_size=<sp>, gpus=<n>, script=<script>
- **W&B run**: <wandb_run or "pending">
- **Duration**: <duration or "in progress">
- **Key metrics**: loss=<loss>, step_time=<step_time>, grad_norm=<grad_norm>
- **Checkpoint**: <checkpoint or "N/A">
- **Insight**: <insight or "pending">
- **Status**: <status>
- **Related lessons**: <lessons or "none">
```
### 3. Insert at the top of the journal
New entries go at the top of the file (after the header), so the most recent
experiments are always visible first.
### 4. Warn on duplicates
If a similar experiment name exists with `status: completed`, warn that this
may be a repeat. If it's `status: running`, assume this is an update.
## Outputs
- Updated `.agents/memory/experiment-journal/README.md`.
## Example Usage
```
Log a completed experiment:
name: wan-t2v-finetune-lr5e5-sp4
config: model=wan-t2v-1.3B, lr=5e-5, sp_size=4, gpus=4
wandb_run: fastvideo/training/run_abc123
duration: 2h 15m
metrics: {loss: 0.065, step_time: 2.3, grad_norm: 0.35}
checkpoint: outputs/wan_finetune/checkpoint-1000
insight: LR 5e-5 converges 30% faster than 1e-5 with no quality loss
status: completed
```
## References
- `.agents/memory/experiment-journal/README.md` — journal file
- `.agents/workflows/experiment-lifecycle.md` — when to log
## Changelog
| Date | Change |
|------|--------|
| 2026-03-02 | Initial version |
-134
View File
@@ -1,134 +0,0 @@
---
name: monitor-experiment
description: Poll a running W&B training run for progress and emit structured alerts
---
# Monitor Experiment
## Purpose
Continuously (or on-demand) check a running experiment's W&B metrics and emit
alerts for anomalies. Supports the "30-minute quality check" paradigm: after
the first 30 minutes of a long training run, produce a checkpoint quality
report before committing more resources.
## Prerequisites
- `WANDB_API_KEY` is set in the environment.
- The experiment is actively logging to W&B (not in `WANDB_MODE=offline`).
- For offline mode: read from local `wandb-summary.json` instead.
## Inputs
| Parameter | Required | Description |
|-----------|----------|-------------|
| `run_id` | Yes* | W&B run ID (e.g., `entity/project/run_id`) |
| `output_dir` | Yes* | Local output directory (for offline mode fallback) |
| `poll_interval` | No | Seconds between polls (default: 60) |
| `alert_on` | No | List of alert conditions to enable (default: all) |
\* One of `run_id` or `output_dir` is required.
## Steps
### 1. Connect to the run
**Online mode** (preferred):
```python
import wandb
api = wandb.Api()
run = api.run("<run_id>")
```
**Offline fallback**:
```python
import json
summary_path = f"{output_dir}/tracker/wandb/latest-run/files/wandb-summary.json"
with open(summary_path) as f:
summary = json.load(f)
```
### 2. Track key metrics
| Metric | W&B Key | Description |
|--------|---------|-------------|
| Training loss | `train_loss` | Primary training loss |
| Gradient norm | `grad_norm` | Gradient magnitude |
| Step time | `step_time` | Wall-clock seconds per step |
| Learning rate | `learning_rate` | Current LR |
| Avg step time | `avg_step_time` | Running average step time |
| Validation videos | `validation_videos_*` | Generated validation samples |
### 3. Evaluate alert conditions
| Alert | Condition | Severity |
|-------|-----------|----------|
| **Loss spike** | `current_loss > 3 × rolling_avg_loss` | 🔴 Critical |
| **NaN/Inf gradient** | `grad_norm` is NaN or Inf | 🔴 Critical |
| **Step time regression** | `step_time > 2 × baseline_step_time` | 🟡 Warning |
| **No progress** | No new W&B logs for > 10 minutes | 🟡 Warning |
| **Loss plateau** | Loss change < 1% over last 100 steps | 🟢 Info |
### 4. Emit structured status
Output format (agent-consumable):
```json
{
"run_id": "...",
"step": 500,
"metrics": {
"train_loss": 0.078,
"grad_norm": 0.41,
"step_time": 2.5,
"learning_rate": 1e-6
},
"alerts": [
{"type": "loss_spike", "severity": "critical", "message": "Loss jumped to 0.45 (avg: 0.08)"}
],
"status": "running"
}
```
### 5. 30-Minute Quality Check
After the first 30 minutes of wall-clock time:
1. Summarize the loss curve shape (decreasing? at what rate?).
2. Check if validation videos have been generated.
3. Report step count, loss at start vs. current, and estimated time to completion.
4. Produce a go/no-go recommendation.
```markdown
## 30-Minute Check: <run_name>
- **Steps completed**: 150
- **Loss**: 0.12 → 0.08 (↓ 33%)
- **Grad norm**: stable at ~0.4
- **Step time**: 2.5s/step (consistent)
- **Validation videos**: 5 generated at step 100
- **Recommendation**: ✅ Continue — loss is decreasing normally
```
## Outputs
- Structured JSON status updates.
- Alert messages for anomalous conditions.
- 30-minute checkpoint quality report.
## Example Usage
```
Monitor W&B run "fastvideo/Wan_distillation/abc123":
run_id: fastvideo/Wan_distillation/abc123
poll_interval: 120
alert_on: [loss_spike, nan_gradient, step_time_regression]
```
## References
- `fastvideo/training/trackers.py` — `WandbTracker` implementation
- `fastvideo/tests/training/Vanilla/test_training_loss.py` — how summaries are compared
- `fastvideo/tests/training/Vanilla/a40_reference_wandb_summary.json` — reference summary format
## Changelog
| Date | Change |
|------|--------|
| 2026-03-02 | Initial version |
@@ -1,343 +0,0 @@
---
name: reseed-ssim-references
description: Re-seed HF reference videos for a single existing SSIM test on Modal L40S. Always backs up current refs locally first, regenerates on Modal, pauses for the user to eyeball before-vs-after quality, then overwrites the targeted `<model_id>` subtree on `FastVideo/ssim-reference-videos` with `--force`. Use when an intentional code change (model port fix, attention backend swap, kernel upgrade, hyperparameter change) has invalidated existing refs and they need to be regenerated. Pairs with `seed-ssim-references`, which is for first-time seeding only.
---
# Re-seed SSIM Reference Videos
## Purpose
Replace the existing SSIM reference videos for a single `(test_file, model_id)`
pair on the HF dataset (`FastVideo/ssim-reference-videos`). This is **destructive**
on HF — the old refs are overwritten — so the skill always:
1. Confirms intent with a one-liner the user has to type.
2. Downloads the existing refs as a local, timestamped backup.
3. Regenerates on Modal L40S (same code path that CI uses).
4. Pauses for a side-by-side eyeball of backup vs new mp4s.
5. Uploads with `--force`, scoped to the single `--model-id`.
6. Reminds the user to keep the backup until the PR lands.
Pairs with `seed-ssim-references`, which is the inverse (first-time seeding
only, refuses to overwrite). Re-seeding is intentionally a separate, more
ceremonial operation because mistakenly clobbering production refs is much
harder to recover from than failing closed.
## When to use
- An intentional code change (model port fix, kernel upgrade, attention
backend swap, hyperparameter change in the test itself) has shifted the
expected SSIM output and the existing refs no longer represent the new
ground truth.
- A test is failing in CI **for the right reason** (the new code is correct,
the old refs are stale).
## When not to use
- A test is failing for the **wrong** reason (the port is buggy, not the
refs). Fix the port; re-seeding hides the bug.
- A brand-new test that has no refs on HF yet. Use `seed-ssim-references`.
- "Just to clean up drift" without a concrete code change to point at. The
PR description has to justify *why* refs changed; without a concrete
change, there's nothing to write.
## Inputs
| Parameter | Required | Description |
|-----------|----------|-------------|
| `test_file` | Yes | Path to the SSIM test, e.g. `fastvideo/tests/ssim/test_matrixgame_similarity.py`. Validated against `fastvideo/tests/ssim/test_*_similarity.py`. |
| `model_id` | Yes | Single model id from the test's `*_MODEL_TO_PARAMS`, e.g. `Matrix-Game-2.0-Diffusers-Base`. Re-seed runs are **per model**. For multi-model tests, invoke the skill once per model. |
| `intent_rationale` | Yes | One-line explanation of *why* refs are being regenerated (e.g. "Relax FA-2 head_size whitelist to include 80 — matrix_game now uses FLASH_ATTN instead of TORCH_SDPA"). Recorded in the backup directory and reused in the PR description. |
Hardcoded:
- Modal GPU: **L40S** (matches CI; re-seeding from another SKU produces refs
that L40S CI cannot match).
- Quality tier: **`default`**. `full_quality` is a separate, deliberate
operation.
- HF repo: `FastVideo/ssim-reference-videos` (override via
`FASTVIDEO_SSIM_REFERENCE_HF_REPO`).
- Device folder: `L40S_reference_videos`.
## Prerequisites
The user has confirmed:
- `modal` CLI authenticated.
- `hf` CLI authenticated, **and** `HF_API_KEY` (or `HUGGINGFACE_HUB_TOKEN` /
`HF_TOKEN`) exported with **write** access to
`FastVideo/ssim-reference-videos`.
- The current branch's code is the change that motivated the re-seed (i.e.
`git rev-parse HEAD` is the commit that intentionally invalidated refs).
Fail fast if any of these are missing.
## Steps
### 1. Validate inputs and confirm intent
- Verify `test_file` exists and matches `fastvideo/tests/ssim/test_*_similarity.py`.
- Grep the file for `*_MODEL_TO_PARAMS` and assert `model_id` is one of its
keys. If the file has only a single hardcoded model, accept that model id
as the only valid value.
- Print the rationale and ask the user to type **`confirm reseed`** (not just
`y` — make it deliberate):
> About to RE-SEED references for model `<model_id>` from test `<test_file>`.
> This will OVERWRITE existing refs on
> `FastVideo/ssim-reference-videos/reference_videos/default/L40S_reference_videos/<model_id>/`
> after backup + Modal regen + eyeball.
>
> Reason: `<intent_rationale>`
> HEAD: `<git rev-parse --short=12 HEAD>`
>
> Reply `confirm reseed` to proceed, anything else to abort.
Stop until the user types exactly `confirm reseed`. Anything else aborts
with no side effects.
### 2. Back up existing refs
Always required. The backup is the only graceful path back if anything goes
wrong later.
```bash
SHORT_COMMIT=$(git rev-parse --short=12 HEAD)
TIMESTAMP=$(date -u +%Y%m%d_%H%M%S)
MODEL_SAFE=$(echo "<model_id>" | tr '/' '_')
BACKUP_DIR="ssim_reseed_backup/${TIMESTAMP}_${SHORT_COMMIT}_${MODEL_SAFE}"
mkdir -p "$BACKUP_DIR"
hf download \
--repo-type dataset FastVideo/ssim-reference-videos \
--include "reference_videos/default/L40S_reference_videos/<model_id>/**" \
--local-dir "$BACKUP_DIR"
mp4_count=$(find "$BACKUP_DIR" -name "*.mp4" | wc -l)
echo "Backup mp4 count: $mp4_count"
[ "$mp4_count" -gt 0 ] || {
echo "ERROR: backup is empty for <model_id>. Either the model id is wrong"
echo "or there are no existing refs (use seed-ssim-references instead)."
exit 1
}
# Provenance — used in the PR description
cat > "$BACKUP_DIR/PROVENANCE.txt" <<EOF
test_file: <test_file>
model_id: <model_id>
head_commit: $(git rev-parse HEAD)
timestamp_utc: $(date -u +%FT%TZ)
reason: <intent_rationale>
EOF
```
If the `hf download` produces zero mp4s, abort — the user has either picked a
non-existent `model_id` or there are no refs yet (in which case
`seed-ssim-references` is the right tool).
### 3. Regenerate on Modal L40S
Mirror CI's exact env recipe so the regenerated refs are byte-comparable to
what CI will produce on the same commit. Two differences from CI:
1. **Pass the same env prefix CI uses** (`IMAGE_VERSION`, `BUILDKITE_*`) — see
`.buildkite/pipeline.yml:1-3` and `.buildkite/scripts/pr_test.sh:62-83`.
Without this, `ssim_test.py:17-18` resolves a different GHCR image tag
(default is `latest`, CI is `py3.12-latest`), and `ssim_test.py:38-46`
bakes different values into the image's frozen env block. **Mismatched
image or env is the most common source of SSIM drift between reseed and
CI runs.**
2. **Do not pass `--skip-reference-download`**. Letting the test fetch the
existing refs and run the full SSIM compare gives "before" SSIM numbers
for the PR description, and the test still produces the new mp4s
regardless of whether the comparison passes or fails.
```bash
SUBDIR="${TIMESTAMP}_${SHORT_COMMIT}"
IMAGE_VERSION="py3.12-latest" \
BUILDKITE_REPO="$(git config --get remote.origin.url)" \
BUILDKITE_COMMIT="$(git rev-parse HEAD)" \
BUILDKITE_PULL_REQUEST="${BUILDKITE_PULL_REQUEST:-false}" \
modal run fastvideo/tests/modal/ssim_test.py \
--git-repo="$(git config --get remote.origin.url)" \
--git-commit="$(git rev-parse HEAD)" \
--hf-api-key="$HF_API_KEY" \
--test-files="<test_file>" \
--sync-generated-to-volume \
--generated-volume-subdir="$SUBDIR" \
--no-fail-fast
```
Capture the printed `modal volume get ...` hint — its `<SUBDIR>` matches
`$SUBDIR` and is needed for step 4. Capture the SSIM numbers from the test
output (or from the JSON next to the generated mp4) for the PR description.
### 4. Download generated videos
```bash
modal volume get --force hf-model-weights \
ssim_generated_videos/default/"$SUBDIR"/generated_videos \
./generated_videos_modal/default
```
After this, the new mp4s live at:
```
./generated_videos_modal/default/generated_videos/L40S_reference_videos/<model_id>/<backend>/<prompt>.mp4
```
`--force` is required when `./generated_videos_modal/default` already exists
from a prior run; safe on the first run too.
### 5. PAUSE — user reviews quality side-by-side
Print the diff and the comparison:
```bash
echo "=== File list diff (backup vs new) ==="
diff -u \
<(find "$BACKUP_DIR/reference_videos/default/L40S_reference_videos/<model_id>" -name "*.mp4" \
| sed "s|$BACKUP_DIR/reference_videos/default/L40S_reference_videos/||" | sort) \
<(find ./generated_videos_modal/default/generated_videos/L40S_reference_videos/<model_id> -name "*.mp4" \
| sed "s|./generated_videos_modal/default/generated_videos/L40S_reference_videos/||" | sort) \
|| true
echo
echo "=== SSIM numbers from this run (paste into PR) ==="
find ./generated_videos_modal/default/generated_videos/L40S_reference_videos/<model_id> -name "*_ssim.json" -exec cat {} \;
```
Then stop and tell the user:
> Old refs backed up to `$BACKUP_DIR`.
> New videos in `./generated_videos_modal/default/generated_videos/L40S_reference_videos/<model_id>/`.
>
> Open both in a video player. Confirm the new videos:
> 1. Look correct (no obvious artifacts, no black/static frames).
> 2. Are *intentionally* different from the backup in the way described
> in `<intent_rationale>` (e.g. slight numerical drift only, not a
> different scene / different motion / corrupted output).
>
> Reply **`upload`** to overwrite HF, anything else to abort.
> Aborting leaves the backup and new videos on disk for inspection — nothing
> on HF changes.
Do not proceed until the user types exactly `upload`. If they abort, leave
everything on disk and stop here.
### 6. Copy into the local reference layout
Same as `seed-ssim-references` step 5:
```bash
python fastvideo/tests/ssim/reference_videos_cli.py copy-local \
--quality-tier default \
--device-folder L40S_reference_videos \
--generated-dir ./generated_videos_modal/default/generated_videos/L40S_reference_videos
```
Result: `fastvideo/tests/ssim/reference_videos/default/L40S_reference_videos/<model_id>/<backend>/<prompt>.mp4`.
### 7. Upload with `--force`, scoped to `--model-id`
The `--force` flag is what makes this skill different from `seed-ssim-references`.
Always pair it with `--model-id` so a typo cannot accidentally overwrite a
neighboring model's refs.
```bash
python fastvideo/tests/ssim/reference_videos_cli.py upload \
--quality-tier default \
--device-folder L40S_reference_videos \
--model-id "<model_id>" \
--force
```
The CLI's overwrite guard refuses without `--force`; with `--force` it
overwrites only files under
`reference_videos/default/L40S_reference_videos/<model_id>/`.
### 8. Report success and retention guidance
Print:
- The HF path that was overwritten (`<repo>/reference_videos/default/L40S_reference_videos/<model_id>/`).
- The local backup directory path.
- The new SSIM numbers from step 5.
- This restore command, in case the PR review surfaces a problem after
upload:
```bash
python fastvideo/tests/ssim/reference_videos_cli.py upload \
--quality-tier default \
--device-folder L40S_reference_videos \
--model-id "<model_id>" \
--reference-dir "$BACKUP_DIR/reference_videos/default/L40S_reference_videos" \
--force
```
- This PR-description checklist (see `fastvideo/tests/ssim/AGENTS.md` →
*Updating Reference Videos*):
1. Source commit that produced the new refs (HEAD at re-seed time).
2. Test command and GPU SKU (`L40S`).
3. Before/after SSIM numbers.
4. The `<intent_rationale>` from step 1.
5. A note that the backup lives at `$BACKUP_DIR` and should be retained
until CI on the PR is green.
Do **not** auto-rerun the SSIM test — the user does that as part of the PR.
## Failure modes and how to handle them
- **`HF_API_KEY` unset.** Stop before step 2.
- **Backup is empty (zero mp4s).** Stop before step 3 — the model id is
wrong or the refs don't exist yet (use `seed-ssim-references`).
- **Modal run fails before generation.** No mp4s on the volume. Don't
upload. Investigate the failure (test crash, OOM, partition exhaustion),
fix, then retry from step 3. Backup is still intact.
- **Quality regressed (visual or metric).** User aborts at step 5. Backup
retained. New videos retained on disk for inspection. Nothing on HF
changed. Either fix the underlying code change or abandon the re-seed.
- **User confirmed `upload` but later realized the new refs are wrong.**
Run the restore command from step 8 with the backup `--reference-dir`.
This is exactly why the backup exists.
- **Multi-model test, only one model is being re-seeded.** Run the skill
once per model id. The `--model-id` scope on upload guarantees the others
are untouched.
## Design notes (for future skill maintainers)
- Per-`model_id` scope is mandatory. The dataset houses many model subtrees;
re-seeding the wrong one is hard to undo without backup.
- `default` tier only; `full_quality` is a separate, deliberate operation
with different params and ~doubled runtime, and isn't what CI gates on.
- The skill deliberately does **not** pass `--skip-reference-download` to
Modal so we get pre-reseed SSIM numbers for the PR. The `seed`-skill
passes it because no refs exist yet; for re-seed, refs do exist and
exposing the comparison is informative.
- The two-token confirm (`confirm reseed`, then `upload`) is intentional.
Re-seeding is high-blast-radius and should not be one-keystroke.
- The backup directory is plain mp4s + `PROVENANCE.txt`. No HF metadata is
preserved; the restore path uses `reference_videos_cli.py upload
--reference-dir` which doesn't need it.
## References
- `.agents/skills/seed-ssim-references/SKILL.md` — the first-time seed
skill this one parallels. Read it for the Modal flag rationale shared
between the two flows.
- `fastvideo/tests/ssim/AGENTS.md` — directory rules, including the PR
expectations for any reference-video change (rationale, before/after
SSIM, source commit/model/backend).
- `fastvideo/tests/ssim/reference_videos_cli.py` — `copy-local`, `upload`
(with `--model-id`, `--force`), `download`. The overwrite guard at
`upload_reference_videos` is the safety net this skill leans on.
- `fastvideo/tests/modal/ssim_test.py` — Modal orchestrator;
`--sync-generated-to-volume`, `--generated-volume-subdir`,
`--skip-reference-download`, `--no-fail-fast`.
## Changelog
| Date | Change |
|------|--------|
| 2026-05-02 | Initial version. Sister skill to `seed-ssim-references`, scoped to single `(test_file, model_id)` re-seeds, with mandatory backup and two-token confirm. |
@@ -1,273 +0,0 @@
---
name: seed-ssim-references
description: Seed HF reference videos for a single newly-added SSIM test. Runs the test on Modal L40S, downloads the generated mp4s via `modal volume get`, pauses for the user to eyeball quality, then uploads only that test's files to `FastVideo/ssim-reference-videos`. Use when a new `fastvideo/tests/ssim/test_*_similarity.py` has just been added and has no references on HF yet.
---
# Seed SSIM Reference Videos
## Purpose
A brand-new SSIM test in `fastvideo/tests/ssim/` fails forever until its
reference videos exist on the HF dataset (`FastVideo/ssim-reference-videos`).
This skill:
1. Runs the test on Modal's L40S pool to generate the videos.
2. Downloads them to the local repo via `modal volume get`.
3. Pauses so the user can eyeball the mp4s and confirm quality.
4. Uploads only the new test's files to HF, with a guard that refuses to
overwrite anything already present.
The skill is run **manually**, once per new test. Before invoking it, the user
has already sanity-tested the new test locally — it launches `VideoGenerator`
and writes an mp4 without crashing. The skill does not re-test locally; it
goes straight to Modal L40S (which is what CI uses).
## When to use
- A new `test_*_similarity.py` file has been added in `fastvideo/tests/ssim/`
and the HF dataset has no `reference_videos/default/L40S_reference_videos/<model_id>/`
subtree for it yet.
## When not to use
- Regular CI runs — once refs exist, `pytest fastvideo/tests/ssim/` downloads
them automatically.
- Re-seeding an existing test. That requires `--force` on the upload step, and
is out of scope here; treat as a separate, deliberate operation.
## Inputs
The skill has **one required input**: the path to the new SSIM test file.
Prompt the user for it if they didn't supply it.
| Parameter | Required | Description |
|-----------|----------|-------------|
| `test_file` | Yes | e.g. `fastvideo/tests/ssim/test_ltx2_similarity.py`. The skill's first action is to ask for this if missing. |
Everything else is fixed:
- Modal runner GPU: **L40S** (hardcoded in `fastvideo/tests/modal/ssim_test.py`).
- Device folder: `L40S_reference_videos`.
- Quality tier: `default` (the tier CI runs). The `full_quality` tier is not
seeded by this skill.
- HF repo: `FastVideo/ssim-reference-videos` (dataset).
- Multi-model test files: all model ids in `*_MODEL_TO_PARAMS` are seeded
together; the Modal run produces one mp4 per (model, prompt, backend) and
the upload scopes by `--model-id`, looping if there is more than one.
## Prerequisites
The user has confirmed:
- `modal` CLI authenticated.
- `HF_API_KEY` (or `HUGGINGFACE_HUB_TOKEN` / `HF_TOKEN`) exported with write
access to `FastVideo/ssim-reference-videos`.
- The test file runs locally end-to-end (generates an mp4; SSIM assertion
failure due to missing reference is expected and fine).
Fail fast if the token env var is missing.
## Steps
### 1. Ask for the test file
If the user didn't name one, ask: *"Which SSIM test file do you want to seed
references for? (e.g. `fastvideo/tests/ssim/test_ltx2_similarity.py`)"*.
Validate:
- Path exists and matches `fastvideo/tests/ssim/test_*_similarity.py`.
- File defines a `*_MODEL_TO_PARAMS` dict — grep it to extract the set of
model ids. Those ids drive step 5.
If either check fails, stop and tell the user what's wrong.
### 2. Run the test on Modal L40S
Pick a subdir name so repeated runs don't collide:
```bash
SHORT_COMMIT=$(git rev-parse --short=12 HEAD)
TIMESTAMP=$(date -u +%Y%m%d_%H%M%S)
SUBDIR="${TIMESTAMP}_${SHORT_COMMIT}"
```
Then launch the Modal run. The `IMAGE_VERSION` and `BUILDKITE_*` env-prefix
**must** match what CI exports in `.buildkite/scripts/pr_test.sh`, otherwise
`fastvideo/tests/modal/ssim_test.py` resolves a different GHCR image tag
(default is `latest`, CI is `py3.12-latest`) and bakes different values into
the image's frozen env block (`ssim_test.py:17-18, 38-46`). Mismatched image
or env produces SSIM drift that doesn't show up until the same commit runs
in CI.
```bash
IMAGE_VERSION="py3.12-latest" \
BUILDKITE_REPO="$(git config --get remote.origin.url)" \
BUILDKITE_COMMIT="$(git rev-parse HEAD)" \
BUILDKITE_PULL_REQUEST="${BUILDKITE_PULL_REQUEST:-false}" \
modal run fastvideo/tests/modal/ssim_test.py \
--git-repo="$(git config --get remote.origin.url)" \
--git-commit="$(git rev-parse HEAD)" \
--hf-api-key="$HF_API_KEY" \
--test-files="<test_file>" \
--sync-generated-to-volume \
--generated-volume-subdir="$SUBDIR" \
--skip-reference-download \
--no-fail-fast
```
Env prefix rationale (parity with CI; see `.buildkite/pipeline.yml:1-3` and
`.buildkite/scripts/pr_test.sh:62-83`):
- `IMAGE_VERSION=py3.12-latest`: pins the Modal image tag to the same one CI
uses. Without this, `ssim_test.py:17` falls back to `latest`, which on
GHCR is built from `Dockerfile.python3.10` — different Python, torch, and
flash-attn wheel than CI's `py3.12-latest` (`infra-build-image.yml:51-67`,
`_template-build-image.yml:65-101`).
- `BUILDKITE_REPO`/`BUILDKITE_COMMIT`/`BUILDKITE_PULL_REQUEST`: mirror what
Buildkite exports. `ssim_test.py:38-46` bakes these into the image's
`.env(...)` block; mismatched values can perturb in-container code paths
that branch on PR-vs-non-PR. `false` for `BUILDKITE_PULL_REQUEST` matches
Buildkite's "non-PR build" sentinel.
Flag rationale:
- `--skip-reference-download`: no refs exist yet, so conftest must not try to
pull them.
- `--no-fail-fast`: lets the test finish generation before `_assert_similarity`
raises `FileNotFoundError: Reference video folder does not exist`. The
expected failure is what we want — the mp4 has already been written.
- `--sync-generated-to-volume` + `--generated-volume-subdir`: copies the
generated mp4s to the `hf-model-weights` Modal volume under
`ssim_generated_videos/default/<SUBDIR>/generated_videos/` so we can pull
them locally.
The Modal run will end with a nonzero exit (expected) and print a
`modal volume get hf-model-weights ssim_generated_videos/default/<SUBDIR>/generated_videos ./generated_videos_modal/default`
command. Capture that `<SUBDIR>` — you need it for step 3.
### 3. Download generated videos locally
```bash
modal volume get --force hf-model-weights \
ssim_generated_videos/default/"$SUBDIR"/generated_videos \
./generated_videos_modal/default
```
`--force` is required when the parent `./generated_videos_modal/default`
already exists; without it, `modal volume get` errors with `[Errno 21] Is a
directory`. Safe to pass on the first run too.
After this, the mp4s live at
`./generated_videos_modal/default/generated_videos/L40S_reference_videos/<model_id>/<backend>/<prompt>.mp4`.
The extra `generated_videos/` level comes from the volume layout in
`_sync_generated_videos_to_volume` (`ssim_test.py`) — the command copies
`<repo>/fastvideo/tests/ssim/generated_videos/<tier>` to
`ssim_generated_videos/<tier>/<SUBDIR>/generated_videos/`, and `modal volume
get` preserves that trailing `generated_videos/` segment.
### 4. PAUSE — user reviews quality
Print the list of downloaded mp4s and their paths, then stop. Tell the user:
> "Generated videos downloaded to `./generated_videos_modal/default/generated_videos/L40S_reference_videos/`. Please open them and confirm the quality looks correct. Reply **`upload`** to continue, or anything else to abort."
Do not proceed until the user explicitly says `upload`. If they abort, leave
everything on disk so they can inspect further — no cleanup.
### 5. Copy into the local reference layout
Scoped copy — only the new test's mp4s. Loop over each `<model_id>` extracted
in step 1:
```bash
python fastvideo/tests/ssim/reference_videos_cli.py copy-local \
--quality-tier default \
--device-folder L40S_reference_videos \
--generated-dir ./generated_videos_modal/default/generated_videos/L40S_reference_videos
```
(The `--generated-dir` points at the device-folder root inside the
downloaded tree; `copy-local` walks all `<model>/<backend>/*.mp4`
underneath it. Since the Modal run was scoped to a single test file via
`--test-files`, only that test's model(s) are present — so the copy is
implicitly per-test.)
Result: `fastvideo/tests/ssim/reference_videos/default/L40S_reference_videos/<model_id>/<backend>/<prompt>.mp4`.
### 6. Upload to HF — scoped per model_id, with overwrite guard
For each `<model_id>`:
```bash
python fastvideo/tests/ssim/reference_videos_cli.py upload \
--quality-tier default \
--device-folder L40S_reference_videos \
--model-id "<model_id>"
```
The upload command:
- Uploads **only** `reference_videos/default/L40S_reference_videos/<model_id>/`.
- **Refuses** if any file already exists at that path on HF (this is the
guard — seeding a new test should never clobber existing refs). To override,
the user must re-run with `--force`. If the guard fires, stop and report
exactly which files exist; do not silently `--force`.
Reads the HF token from `HF_API_KEY` / `HUGGINGFACE_HUB_TOKEN` / `HF_TOKEN`.
### 7. Report success
List what was uploaded (paths in repo) and remind the user to push any
related code changes. Do **not** auto-verify by re-running Modal — the user
can run `pytest fastvideo/tests/ssim/<test_file>` later to confirm end-to-end;
it will auto-download the refs they just uploaded.
## Failure modes and how to handle them
- **`HF_API_KEY` unset.** Stop before step 2. The Modal run needs it (passed
via `--hf-api-key`), and step 6 needs it for upload.
- **Modal run fails before generation.** No mp4s on the volume — nothing to
download. Fix the test locally (`pytest fastvideo/tests/ssim/<test_file>`)
and retry from step 2.
- **`./generated_videos_modal/default/L40S_reference_videos/` missing after
`modal volume get`.** The run didn't produce videos (most likely the test
crashed before writing, or `REQUIRED_GPUS` exceeded the partition capacity
— see Modal logs).
- **Upload guard fires (files already exist).** The test name / model id
collides with something already on HF. Verify the user actually wants to
replace existing refs; if so, re-run the upload with `--force`. If not,
rename the model id in `*_MODEL_TO_PARAMS` and re-seed.
- **Quality looks wrong in step 4.** Abort. The mp4s stay on disk for
inspection. The fix is usually in the test's params (resolution, steps,
seed) — edit the test, then re-run the skill.
## Design notes (for future skill maintainers)
- The skill deliberately runs on Modal, **not** locally, because the CI
runner is L40S. Seeding from a different GPU SKU produces refs that CI's
L40S runs can't match (SSIM drifts across SKUs).
- The skill is default-tier only. `full_quality` refs are seeded by a
separate, deliberate operation — they double runtime and aren't what CI
gates on.
- The overwrite guard in `reference_videos_cli.py upload` is default-on
specifically because this skill exists. Re-seeding is a distinct operation
that requires explicit `--force`.
## References
- `fastvideo/tests/modal/ssim_test.py` — Modal orchestrator; see
`--sync-generated-to-volume`, `--generated-volume-subdir`,
`--skip-reference-download`, `--no-fail-fast`.
- `fastvideo/tests/ssim/reference_videos_cli.py` — `copy-local`, `upload`
(with `--model-id`, `--force`), `download`, `ensure` subcommands.
- `fastvideo/tests/ssim/README.md` — reference layout, HF repo conventions.
- `fastvideo/tests/ssim/inference_similarity_utils.py` —
`run_text_to_video_similarity_test` + `_build_init_kwargs`: what each test
config passes to `VideoGenerator.from_pretrained`.
## Changelog
| Date | Change |
|------|--------|
| 2026-04-17 | Initial version (Modal sync-to-volume flow). |
| 2026-04-21 | Rewrite: single-test scope, explicit user-review pause, per-`model_id` upload, HF overwrite guard. Dropped `scripts/seed_ssim.sh`. |
| 2026-04-21 | Post-first-run fixes: `modal volume get` needs `--force` when parent exists; download tree has an extra `generated_videos/` level so `--generated-dir` must reflect it. |
-137
View File
@@ -1,137 +0,0 @@
---
name: summarize-run
description: Extract a W&B run summary into a structured experiment report
---
# Summarize Run
## Purpose
After a training run completes (or at any checkpoint), extract key metrics from
the W&B run summary and produce a structured markdown report. Supports both
online (W&B API) and offline (local `wandb-summary.json`) modes.
## Prerequisites
- Run has completed or reached a checkpoint with a saved summary.
- For online: `WANDB_API_KEY` set in environment.
- For offline: access to `<output_dir>/tracker/wandb/latest-run/files/wandb-summary.json`.
## Inputs
| Parameter | Required | Description |
|-----------|----------|-------------|
| `run_id` | Yes* | W&B run ID for online access |
| `output_dir` | Yes* | Local output dir for offline access |
| `reference_run` | No | Path to reference `wandb-summary.json` for comparison |
| `experiment_name` | No | Name for the journal entry (default: from W&B) |
\* One of `run_id` or `output_dir` is required.
## Steps
### 1. Load run summary
**Online**:
```python
import wandb
api = wandb.Api()
run = api.run("<run_id>")
summary = dict(run.summary)
config = dict(run.config)
```
**Offline** (existing codebase pattern from `fastvideo/tests/training/`):
```python
import json
summary_path = f"{output_dir}/tracker/wandb/latest-run/files/wandb-summary.json"
with open(summary_path) as f:
summary = json.load(f)
```
### 2. Extract key fields
| Field | Source | Description |
|-------|--------|-------------|
| `train_loss` | `summary["train_loss"]` | Final training loss |
| `avg_step_time` | `summary["avg_step_time"]` | Average seconds per step |
| `step_time` | `summary["step_time"]` | Last step time |
| `grad_norm` | `summary["grad_norm"]` | Final gradient norm |
| `learning_rate` | `summary["learning_rate"]` | Final LR |
| `_step` | `summary["_step"]` | Total steps completed |
| `_runtime` | `summary["_runtime"]` | Total wall-clock seconds |
| `validation_videos_*` | `summary[key]` | Validation video artifacts |
### 3. Compare against reference (optional)
Follow the pattern in `fastvideo/tests/training/Vanilla/test_training_loss.py`:
```python
# Fields to compare
compare_fields = ["train_loss", "grad_norm", "avg_step_time"]
tolerance = 0.05 # 5% relative tolerance
for field in compare_fields:
ref_val = reference_summary[field]
cur_val = summary[field]
diff_pct = abs(cur_val - ref_val) / abs(ref_val) * 100
status = "✅" if diff_pct < tolerance * 100 else "⚠️"
print(f"{status} {field}: {cur_val:.4f} (ref: {ref_val:.4f}, diff: {diff_pct:.1f}%)")
```
### 4. Generate report
```markdown
# Run Summary: <experiment_name>
| Metric | Value | Reference | Diff |
|--------|-------|-----------|------|
| Train Loss | 0.0788 | 0.0800 | -1.5% ✅ |
| Avg Step Time | 2.81s | 2.80s | +0.4% ✅ |
| Grad Norm | 0.408 | 0.410 | -0.5% ✅ |
| Total Steps | 500 | — | — |
| Wall Time | 23m 30s | — | — |
## Configuration
- Model: Wan-AI/Wan2.1-T2V-1.3B-Diffusers
- Learning Rate: 1e-6
- Batch Size: 1
- GPUs: 8 × (SP=1, TP=1)
- Mixed Precision: bf16
## Validation Videos
<list of validation video paths if available>
## Notes
<any observations or anomalies>
```
### 5. Update experiment journal
Append or update the experiment's entry in `.agents/memory/experiment-journal/README.md`
with the final metrics and status.
## Outputs
- Structured markdown report.
- Updated experiment journal entry.
## Example Usage
```
Summarize the run in output directory "outputs/wan_finetune":
output_dir: outputs/wan_finetune
reference_run: fastvideo/tests/training/Vanilla/a40_reference_wandb_summary.json
experiment_name: wan-t2v-finetune-lr1e6
```
## References
- `fastvideo/tests/training/Vanilla/test_training_loss.py` — reference comparison pattern
- `fastvideo/tests/training/Vanilla/a40_reference_wandb_summary.json` — example summary
- `fastvideo/tests/training/lora/test_lora_training.py` — LoRA summary comparison
- `fastvideo/training/trackers.py` — tracker summary generation
## Changelog
| Date | Change |
|------|--------|
| 2026-03-02 | Initial version |
@@ -1,54 +0,0 @@
---
description: How to develop, validate, and register a new evaluation metric
---
# Evaluation Development SOP
Standard procedure for adding new video quality evaluation metrics to the
FastVideo agent toolkit.
## When to Use
- You need a metric that doesn't exist in `.agents/memory/evaluation-registry/README.md`.
- An existing metric needs significant changes to its methodology.
- You're exploring a new evaluation approach.
## Steps
### 1. Research
- Search `.agents/memory/related-work/` for existing evaluation approaches.
- Check the `evaluation_registry.md` for current metrics and their limitations.
- Review literature: FVD, CLIP-Score, human preference, etc.
### 2. Prototype
- Write a standalone script in `.agents/exploration/<metric-name>.md`.
- Keep it simple: one script, minimal dependencies.
- Test on a few known-good and known-bad video samples.
### 3. Validate
- **Known-good test**: Metric should score high on reference-quality videos.
- **Known-bad test**: Metric should score low on degraded/unrelated videos.
- **Sensitivity test**: Small quality differences should produce meaningful
score differences.
- Document thresholds and their justification.
### 4. Register
Update `.agents/memory/evaluation-registry/README.md`:
- Add the metric with status `Active`.
- Document location, thresholds, and trust level.
### 5. Integrate
Update `.agents/skills/evaluate-video-quality.md`:
- Add the new metric as a section.
- Include code examples and interpretation guide.
### 6. Document
- Move the exploration log content into the skill.
- Clean up the exploration file or mark it as `promoted`.
- If anything went wrong during development, create a lesson.
@@ -1,47 +0,0 @@
---
description: When and how to log experiments in the experiment journal
---
# Experiment Journaling SOP
Ensures every experiment is properly recorded with context and outcomes.
## When to Log
**Always.** Every experiment — even quick tests — should be journaled.
## Steps
### 1. Before Launch — Create Draft Entry
Use the `log-experiment` skill with `status: running`:
- Include hypothesis and config.
- Leave metrics, duration, and insight blank.
### 2. After 30-Minute Check — Update with Initial Metrics
Update the entry with:
- Current loss and its trajectory direction.
- Step time.
- Number of validation videos generated.
- Preliminary go/no-go assessment.
### 3. On Completion — Fill Final Entry
Update the entry with `status: completed`:
- Final loss, grad norm, avg step time.
- Total duration and steps.
- Checkpoint path.
- Key insight.
### 4. On Failure — Document Failure Mode
Update the entry with `status: failed`:
- What went wrong (OOM, NaN, crash, etc.).
- At what step the failure occurred.
- Create a lesson in `.agents/lessons/` for non-trivial failures.
### 5. Cross-Reference
- Link related lessons: `**Related lessons**: .agents/lessons/<filename>.md`
- Link related experiments: if this is a follow-up, reference the prior entry.
-87
View File
@@ -1,87 +0,0 @@
---
description: End-to-end experiment lifecycle from hypothesis to lessons learned
---
# Experiment Lifecycle SOP
Standard operating procedure for running ML training experiments on
FastVideo-WorldModel. Every experiment should follow this flow.
## Overview
```
Plan → Launch → Monitor → Summarize → Journal → Reflect
```
## Steps
### 1. Plan the Experiment
Before launching:
- [ ] Define a clear **hypothesis** (what you expect to learn).
- [ ] Select the **model** and **pipeline** type (finetune, distill, lora, etc.).
- [ ] Prepare the **dataset** (preprocessed into parquet format).
- [ ] Review existing experiments in `.agents/memory/experiment-journal/README.md` for related work.
- [ ] Check `.agents/lessons/` for known pitfalls with this configuration.
- [ ] Document the plan in the experiment journal as a draft entry.
### 2. Launch the Experiment
Use the `launch-experiment` skill:
- Provide: pipeline, model, data_path, num_gpus, and any hyperparameter overrides.
- The skill generates the `torchrun` command and creates a journal entry.
- Verify the command looks correct before executing.
Reference: `.agents/skills/launch-experiment.md`
### 3. Monitor the Experiment
Use the `monitor-experiment` skill:
- Provide the W&B run ID (or output_dir for offline).
- Monitor alerts: loss spikes, NaN gradients, step time regressions.
- At the **30-minute mark**: perform the quality check.
- Is loss decreasing?
- Are validation videos reasonable?
- Is step time consistent?
- **Decision point**: Continue or abort based on the 30-min check.
Reference: `.agents/skills/monitor-experiment.md`
### 4. Summarize the Run
After completion (or at any checkpoint), use the `summarize-run` skill:
- Extract final metrics from W&B summary.
- Compare against reference runs if available.
- Generate a structured report.
Reference: `.agents/skills/summarize-run.md`
### 5. Update the Experiment Journal
Use the `log-experiment` skill to update the journal entry:
- Fill in final metrics, duration, checkpoint paths.
- Record the key insight learned.
- Set status to `completed`, `failed`, or `abandoned`.
Reference: `.agents/skills/log-experiment.md`
### 6. Reflect and Capture Lessons
After every experiment:
- **What went right?** → Note in the journal insight field.
- **What went wrong?** → Create a lesson in `.agents/lessons/`:
- Use the template in `.agents/lessons/README.md`.
- Cross-reference the experiment journal entry.
- **What was surprising?** → Consider creating an exploration log if this
warrants further investigation.
Reference: `.agents/workflows/lesson-capture.md`
## Validation Criteria
This SOP is validated when an agent can:
1. Follow steps 1–6 end-to-end for a minimal training run
(e.g., `examples/training/finetune/wan_t2v_1.3B/crush_smol/finetune_t2v.sh`
with `--max_train_steps 5`).
2. Produce a complete experiment journal entry.
3. Generate a run summary report.
-71
View File
@@ -1,71 +0,0 @@
---
description: Post-experiment reflection to capture lessons learned
---
# Lesson Capture SOP
Systematic procedure for turning experiment outcomes into persistent knowledge.
## When to Use
After **every** completed or failed experiment. Even successful experiments
can yield lessons (e.g., "LR 5e-5 works better than 1e-5 for LoRA").
## Steps
### 1. Review the Experiment
Read the experiment journal entry. Ask:
- Did anything go wrong?
- Was anything surprising?
- Did anything take longer than expected?
- Was a workaround needed?
### 2. Decide: Lesson or Not?
| Situation | Action |
|-----------|--------|
| Something broke | Create a lesson (category: `infrastructure` or `data`) |
| Hyperparameter choice mattered | Create a lesson (category: `hyperparameter`) |
| Porting issue found | Create a lesson (category: `porting`) |
| Evaluation metric was misleading | Create a lesson (category: `evaluation`) |
| Everything went smoothly | No lesson needed, but note in the journal insight |
### 3. Create the Lesson File
In `.agents/lessons/`, create `<YYYY-MM-DD>_<short-slug>.md`:
```markdown
---
date: <ISO-8601>
experiment: <journal entry reference>
category: hyperparameter | data | infrastructure | evaluation | porting
severity: critical | important | minor
---
# <Short Descriptive Title>
## What Happened
<description>
## Root Cause
<analysis>
## Fix / Workaround
<resolution>
## Prevention
<how to avoid in future>
```
### 4. Cross-Reference
- Update the experiment journal entry with a link to the lesson file.
- If a similar lesson already exists, add a reference or update it.
### 5. Periodic Pattern Review
Every ~10 lessons, scan for patterns:
- Multiple lessons in the same category → consider a new skill or SOP.
- Repeated mistakes → strengthen the relevant SOP with a checklist item.
- Infrastructure issues → propose a codebase fix.
@@ -1,46 +0,0 @@
{
"benchmark_id": "wan-t2v-1.3b-2gpu",
"description": "Wan2.1 T2V 1.3B inference performance",
"model": {
"model_path": "Wan-AI/Wan2.1-T2V-1.3B-Diffusers",
"model_short_name": "Wan2.1-T2V-1.3B"
},
"init_kwargs": {
"num_gpus": 2,
"flow_shift": 7.0,
"sp_size": 2,
"tp_size": 1,
"vae_sp": true,
"vae_tiling": true,
"text_encoder_precisions": ["fp32"]
},
"generation_kwargs": {
"height": 480,
"width": 832,
"num_frames": 45,
"num_inference_steps": 4,
"guidance_scale": 3,
"embedded_cfg_scale": 6,
"seed": 1024,
"fps": 24,
"neg_prompt": "Bright tones, overexposed, static, blurred details, subtitles, style, works, paintings, images, static, overall gray, worst quality, low quality, JPEG compression residue, ugly, incomplete, extra fingers, poorly drawn hands, poorly drawn faces, deformed, disfigured, misshapen limbs, fused fingers, still picture, messy background, three legs, many people in the background, walking backwards"
},
"test_prompts": [
"Will Smith casually eats noodles, his relaxed demeanor contrasting with the energetic background of a bustling street food market. The scene captures a mix of humor and authenticity. Mid-shot framing, vibrant lighting."
],
"run_config": {
"num_warmup_runs": 2,
"num_measurement_runs": 5,
"required_gpus": 2
},
"thresholds": {
"L40S": {
"max_generation_time_s": 34.0,
"max_peak_memory_mb": 11000.0
},
"default": {
"max_generation_time_s": 120.0,
"max_peak_memory_mb": 30000.0
}
}
}
-438
View File
@@ -1,438 +0,0 @@
env:
IMAGE_VERSION: "py3.12-latest"
BUILDKITE_CLEAN_CHECKOUT: true
notify:
- github_commit_status:
context: "fastcheck-passed"
if: build.env("TEST_SCOPE") == "fastcheck" || build.env("TEST_SCOPE") == null
- github_commit_status:
context: "full-suite-passed"
if: build.env("TEST_SCOPE") == "full"
- github_commit_status:
context: "direct-test-completed"
if: build.env("TEST_SCOPE") == "direct"
steps:
# ============================================================
# Direct test: triggered by /test <name> slash command.
# Labels match fastcheck/full-suite counterparts so the GitHub
# check status overwrites the original failed check.
# Only ONE step executes per build (gated by TEST_TYPE).
# ============================================================
# --- Fastcheck-scope direct tests ---
- label: ":microscope: Encoder Tests"
if: build.env("TEST_SCOPE") == "direct" && build.env("TEST_TYPE") == "encoder"
command: "timeout 90m .buildkite/scripts/pr_test.sh"
retry:
automatic:
- exit_status: 128
limit: 3
- exit_status: -1
limit: 2
agents:
queue: "default"
- label: ":microscope: VAE Tests"
if: build.env("TEST_SCOPE") == "direct" && build.env("TEST_TYPE") == "vae"
command: "timeout 90m .buildkite/scripts/pr_test.sh"
retry:
automatic:
- exit_status: 128
limit: 3
- exit_status: -1
limit: 2
agents:
queue: "default"
- label: ":microscope: Transformer Tests"
if: build.env("TEST_SCOPE") == "direct" && build.env("TEST_TYPE") == "transformer"
command: "timeout 90m .buildkite/scripts/pr_test.sh"
retry:
automatic:
- exit_status: 128
limit: 3
- exit_status: -1
limit: 2
agents:
queue: "default"
- label: ":microscope: Kernel Tests"
if: build.env("TEST_SCOPE") == "direct" && build.env("TEST_TYPE") == "kernel_tests"
command: "timeout 90m .buildkite/scripts/pr_test.sh"
retry:
automatic:
- exit_status: 128
limit: 3
- exit_status: -1
limit: 2
agents:
queue: "default"
- label: ":microscope: Unit Tests"
if: build.env("TEST_SCOPE") == "direct" && build.env("TEST_TYPE") == "unit_test"
command: "timeout 90m .buildkite/scripts/pr_test.sh"
retry:
automatic:
- exit_status: 128
limit: 3
- exit_status: -1
limit: 2
agents:
queue: "default"
# --- Full-suite-scope direct tests ---
- label: ":bar_chart: SSIM Tests"
if: build.env("TEST_SCOPE") == "direct" && build.env("TEST_TYPE") == "ssim"
command: "timeout 90m .buildkite/scripts/pr_test.sh"
retry:
automatic:
- exit_status: 128
limit: 3
- exit_status: -1
limit: 2
- exit_status: 1
limit: 2
agents:
queue: "default"
- label: ":test_tube: LoRA Inference Tests"
if: build.env("TEST_SCOPE") == "direct" && build.env("TEST_TYPE") == "inference_lora"
command: "timeout 90m .buildkite/scripts/pr_test.sh"
retry:
automatic:
- exit_status: 128
limit: 3
- exit_status: -1
limit: 2
agents:
queue: "default"
- label: ":test_tube: Training Tests"
if: build.env("TEST_SCOPE") == "direct" && build.env("TEST_TYPE") == "training"
command: "timeout 90m .buildkite/scripts/pr_test.sh"
retry:
automatic:
- exit_status: 128
limit: 3
- exit_status: -1
limit: 2
agents:
queue: "default"
- label: ":test_tube: Distillation DMD Tests"
if: build.env("TEST_SCOPE") == "direct" && build.env("TEST_TYPE") == "distillation_dmd"
command: "timeout 90m .buildkite/scripts/pr_test.sh"
retry:
automatic:
- exit_status: 128
limit: 3
- exit_status: -1
limit: 2
agents:
queue: "default"
- label: ":test_tube: Self-Forcing Tests"
if: build.env("TEST_SCOPE") == "direct" && build.env("TEST_TYPE") == "self_forcing"
command: "timeout 90m .buildkite/scripts/pr_test.sh"
retry:
automatic:
- exit_status: 128
limit: 3
- exit_status: -1
limit: 2
agents:
queue: "default"
- label: ":test_tube: LoRA Training Tests"
if: build.env("TEST_SCOPE") == "direct" && build.env("TEST_TYPE") == "training_lora"
command: "timeout 90m .buildkite/scripts/pr_test.sh"
retry:
automatic:
- exit_status: 128
limit: 3
- exit_status: -1
limit: 2
- exit_status: 1
limit: 2
agents:
queue: "default"
- label: ":test_tube: Training Tests VSA"
if: build.env("TEST_SCOPE") == "direct" && build.env("TEST_TYPE") == "training_vsa"
command: "timeout 90m .buildkite/scripts/pr_test.sh"
retry:
automatic:
- exit_status: 128
limit: 3
- exit_status: -1
limit: 2
- exit_status: 1
limit: 2
agents:
queue: "default"
- label: ":test_tube: Inference Tests VMoBA"
if: build.env("TEST_SCOPE") == "direct" && build.env("TEST_TYPE") == "inference_vmoba"
command: "timeout 90m .buildkite/scripts/pr_test.sh"
retry:
automatic:
- exit_status: 128
limit: 3
- exit_status: -1
limit: 2
agents:
queue: "default"
- label: ":test_tube: Performance Tests"
if: build.env("TEST_SCOPE") == "direct" && build.env("TEST_TYPE") == "performance"
command: "timeout 90m .buildkite/scripts/pr_test.sh"
retry:
automatic:
- exit_status: 128
limit: 3
- exit_status: -1
limit: 2
agents:
queue: "default"
- label: ":test_tube: API Server Tests"
if: build.env("TEST_SCOPE") == "direct" && build.env("TEST_TYPE") == "api_server"
command: "timeout 90m .buildkite/scripts/pr_test.sh"
retry:
automatic:
- exit_status: 128
limit: 3
- exit_status: -1
limit: 2
agents:
queue: "default"
# ============================================================
# Fastcheck: Runs on every PR (~10-15 min parallel)
# Core component validation: encoders, VAEs, transformers,
# CUDA kernels, and unit tests.
# ============================================================
- label: "Trigger Fastcheck"
if: build.env("TEST_SCOPE") == "fastcheck" || build.env("TEST_SCOPE") == null
retry:
automatic:
- exit_status: 128
limit: 3
- exit_status: -1
limit: 2
plugins:
- monorepo-diff#v1.4.0:
diff: 'git fetch origin "${BUILDKITE_PULL_REQUEST_BASE_BRANCH:-main}" && git diff --name-only "origin/${BUILDKITE_PULL_REQUEST_BASE_BRANCH:-main}...HEAD"'
watch:
- path:
- "fastvideo/models/encoders/**"
- "fastvideo/models/loader/**"
- "fastvideo/tests/encoders/**"
- "pyproject.toml"
- "docker/Dockerfile.python3.12"
config:
command: "timeout 20m .buildkite/scripts/pr_test.sh"
label: ":microscope: Encoder Tests"
env:
- TEST_TYPE=encoder
agents:
queue: "default"
- path:
- "fastvideo/models/vaes/**"
- "fastvideo/models/loader/**"
- "fastvideo/tests/vaes/**"
- "pyproject.toml"
- "docker/Dockerfile.python3.12"
config:
command: "timeout 20m .buildkite/scripts/pr_test.sh"
label: ":microscope: VAE Tests"
env:
- TEST_TYPE=vae
agents:
queue: "default"
- path:
- "fastvideo/models/dits/**"
- "fastvideo/models/loader/**"
- "fastvideo/tests/transformers/**"
- "fastvideo/layers/**"
- "fastvideo/attention/**"
- "pyproject.toml"
- "docker/Dockerfile.python3.12"
config:
command: "timeout 15m .buildkite/scripts/pr_test.sh"
label: ":microscope: Transformer Tests"
env:
- TEST_TYPE=transformer
agents:
queue: "default"
- path:
- "fastvideo-kernel/**"
- "pyproject.toml"
- "docker/Dockerfile.python3.12"
config:
command: "timeout 15m .buildkite/scripts/pr_test.sh"
label: ":microscope: Kernel Tests"
env:
- TEST_TYPE=kernel_tests
agents:
queue: "default"
- path:
- "fastvideo/**"
- ".buildkite/**"
- ".github/**"
- "pyproject.toml"
- "docker/Dockerfile.python3.12"
config:
command: "timeout 15m .buildkite/scripts/pr_test.sh"
label: ":microscope: Unit Tests"
env:
- TEST_TYPE=unit_test
agents:
queue: "default"
# ============================================================
# Full Suite: Runs when TEST_SCOPE=full
# Triggered by adding the 'ready' label (via ci-trigger-full-suite.yml)
# or on-demand via /test full slash command.
# Includes integration tests, SSIM regression, training pipelines,
# and performance benchmarks.
# ============================================================
- label: "Trigger Full Suite"
if: build.env("TEST_SCOPE") == "full"
retry:
automatic:
- exit_status: 128
limit: 3
- exit_status: -1
limit: 2
plugins:
- monorepo-diff#v1.4.0:
diff: 'git fetch origin "${BUILDKITE_PULL_REQUEST_BASE_BRANCH:-main}" && git diff --name-only "origin/${BUILDKITE_PULL_REQUEST_BASE_BRANCH:-main}...HEAD"'
watch:
- path:
- "fastvideo/**/*.py"
- "pyproject.toml"
- "docker/Dockerfile.python3.12"
config:
command: "timeout 90m .buildkite/scripts/pr_test.sh"
label: ":bar_chart: SSIM Tests"
env:
- TEST_TYPE=ssim
retry:
automatic:
- exit_status: 1
limit: 2
agents:
queue: "default"
- path:
- "fastvideo/tests/lora/**"
- "fastvideo/models/loader/**"
- "fastvideo/tests/transformers/**"
- "fastvideo/pipelines/**"
- "fastvideo/layers/lora/**"
- "pyproject.toml"
- "docker/Dockerfile.python3.12"
config:
command: "timeout 20m .buildkite/scripts/pr_test.sh"
label: ":test_tube: LoRA Inference Tests"
env:
- TEST_TYPE=inference_lora
agents:
queue: "default"
- path:
- "fastvideo/**"
- "pyproject.toml"
- "docker/Dockerfile.python3.12"
config:
command: "timeout 15m .buildkite/scripts/pr_test.sh"
label: ":test_tube: Training Tests"
env:
- TEST_TYPE=training
agents:
queue: "default"
- path:
- "fastvideo/training/*distillation_pipeline.py"
- "pyproject.toml"
- "docker/Dockerfile.python3.12"
config:
command: "timeout 15m .buildkite/scripts/pr_test.sh"
label: ":test_tube: Distillation DMD Tests"
env:
- TEST_TYPE=distillation_dmd
agents:
queue: "default"
- path:
- "fastvideo/training/*self_forcing_distillation_pipeline.py"
- "fastvideo/tests/training/self-forcing/**"
- "pyproject.toml"
- "docker/Dockerfile.python3.12"
config:
command: "timeout 15m .buildkite/scripts/pr_test.sh"
label: ":test_tube: Self-Forcing Tests"
env:
- TEST_TYPE=self_forcing
agents:
queue: "default"
- path:
- "fastvideo/**"
- "pyproject.toml"
- "docker/Dockerfile.python3.12"
config:
command: "timeout 15m .buildkite/scripts/pr_test.sh"
label: ":test_tube: LoRA Training Tests"
env:
- TEST_TYPE=training_lora
retry:
automatic:
- exit_status: 1
limit: 2
agents:
queue: "default"
- path:
- "fastvideo/**"
- "fastvideo-kernel/**"
- "pyproject.toml"
- "docker/Dockerfile.python3.12"
config:
command: "timeout 15m .buildkite/scripts/pr_test.sh"
label: ":test_tube: Training Tests VSA"
env:
- TEST_TYPE=training_vsa
retry:
automatic:
- exit_status: 1
limit: 2
agents:
queue: "default"
- path:
- "fastvideo-kernel/**"
- "fastvideo/attention/backends/vmoba.py"
- "pyproject.toml"
- "docker/Dockerfile.python3.12"
config:
command: "timeout 15m .buildkite/scripts/pr_test.sh"
label: ":test_tube: Inference Tests VMoBA"
env:
- TEST_TYPE=inference_vmoba
agents:
queue: "default"
- path:
- "fastvideo/models/dits/**"
- "fastvideo/pipelines/**"
- "fastvideo/attention/**"
- "fastvideo/layers/**"
- "fastvideo/worker/**"
- "fastvideo/entrypoints/**"
- "fastvideo/tests/performance/**"
- ".buildkite/performance-benchmarks/**"
- "pyproject.toml"
- "docker/Dockerfile.python3.12"
config:
command: "timeout 30m .buildkite/scripts/pr_test.sh"
label: ":test_tube: Performance Tests"
env:
- TEST_TYPE=performance
agents:
queue: "default"
- path:
- "fastvideo/entrypoints/openai/**"
- "fastvideo/entrypoints/cli/serve.py"
- "fastvideo/tests/entrypoints/test_openai_api_integration.py"
- "pyproject.toml"
- "docker/Dockerfile.python3.12"
config:
command: "timeout 30m .buildkite/scripts/pr_test.sh"
label: ":test_tube: API Server Tests"
env:
- TEST_TYPE=api_server
agents:
queue: "default"
-235
View File
@@ -1,235 +0,0 @@
#!/bin/bash
set -uo pipefail
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
log "=== Starting Modal test execution ==="
# Change to the project directory
cd "$(dirname "$0")/../.."
PROJECT_ROOT=$(pwd)
log "Project root: $PROJECT_ROOT"
# Install Modal if not available
if ! python3 -m modal --version &> /dev/null; then
log "Modal not found, installing..."
if ! command -v uv &> /dev/null; then
log "uv not found, bootstrapping..."
if ! curl -LsSf https://astral.sh/uv/install.sh | sh; then
log "Error: Failed to bootstrap uv via astral.sh installer."
exit 1
fi
export PATH="$HOME/.local/bin:$PATH"
if ! command -v uv &> /dev/null; then
log "Error: uv still not on PATH after bootstrap."
exit 1
fi
fi
# --break-system-packages preserves prior `pip install --user` semantics on PEP 668 agents.
uv pip install --system --break-system-packages modal
# Verify installation
if ! python3 -m modal --version &> /dev/null; then
log "Error: Failed to install modal. Please install it manually."
exit 1
fi
fi
log "modal version: $(python3 -m modal --version)"
# Set up Modal authentication using Buildkite secrets
log "Setting up Modal authentication from Buildkite secrets..."
MODAL_TOKEN_ID=$(buildkite-agent secret get modal_token_id)
MODAL_TOKEN_SECRET=$(buildkite-agent secret get modal_token_secret)
# Retrieve other secrets
WANDB_API_KEY=$(buildkite-agent secret get wandb_api_key)
HF_API_KEY=$(buildkite-agent secret get hf_api_key)
if [ -n "$MODAL_TOKEN_ID" ] && [ -n "$MODAL_TOKEN_SECRET" ]; then
log "Retrieved Modal credentials from Buildkite secrets"
python3 -m modal token set --token-id "$MODAL_TOKEN_ID" --token-secret "$MODAL_TOKEN_SECRET" --profile buildkite-ci --activate --verify
if [ $? -eq 0 ]; then
log "Modal authentication successful"
else
log "Error: Failed to set Modal credentials"
exit 1
fi
else
log "Error: Could not retrieve Modal credentials from Buildkite secrets."
log "Please ensure 'modal_token_id' and 'modal_token_secret' secrets are set in Buildkite."
exit 1
fi
MODAL_TEST_FILE="fastvideo/tests/modal/pr_test.py"
MODAL_SSIM_TEST_FILE="fastvideo/tests/modal/ssim_test.py"
if [ -z "${TEST_TYPE:-}" ]; then
log "Error: TEST_TYPE environment variable is not set"
exit 1
fi
log "Test type: $TEST_TYPE"
EFFECTIVE_PR=${BUILDKITE_PULL_REQUEST:-false}
if [ "$EFFECTIVE_PR" = "false" ] && [ -n "${PR_NUMBER:-}" ]; then
EFFECTIVE_PR=$PR_NUMBER
fi
MODAL_ENV="BUILDKITE_REPO=$BUILDKITE_REPO BUILDKITE_COMMIT=$BUILDKITE_COMMIT BUILDKITE_PULL_REQUEST=$EFFECTIVE_PR BUILDKITE_BRANCH=${BUILDKITE_BRANCH:-} TEST_SCOPE=${TEST_SCOPE:-} IMAGE_VERSION=$IMAGE_VERSION"
POST_RUN_HOOK=""
upload_performance_artifacts() {
SHORT_SHA=${BUILDKITE_COMMIT:0:7}
LOCAL_DIR="downloaded_reports"
_download_reports() {
log "Downloading perf_reports/ from Modal Volume..."
mkdir -p "$LOCAL_DIR"
if ! modal volume get hf-model-weights "perf_reports/" "$LOCAL_DIR"; then
log "Error: Failed to download perf_reports/ from Modal Volume."
return 1
fi
}
_upload_dashboard() {
local target
target=$(find "$LOCAL_DIR" -name "dashboard_${SHORT_SHA}_*" | head -n 1)
log "TARGET dashboard: '$target'"
if [ -n "$target" ]; then
log "Found dashboard: $target. Uploading to Buildkite..."
buildkite-agent artifact upload "$target"
buildkite-agent annotate --style info --context "perf-dashboard" < "$target"
else
log "Warning: Could not find a dashboard file matching $SHORT_SHA"
fi
}
_upload_perf_summary() {
local target
target=$(find "$LOCAL_DIR" -name "perf_${SHORT_SHA}_*" | head -n 1)
log "TARGET perf summary: '$target'"
if [ -n "$target" ]; then
log "Found perf summary: $target. Uploading to Buildkite..."
buildkite-agent artifact upload "$target"
buildkite-agent annotate --style info --context "perf-summary" < "$target"
else
log "Warning: Could not find a perf summary file matching $SHORT_SHA"
fi
}
_cleanup_modal_volume() {
log "Cleaning up perf_reports/ from Modal Volume..."
if modal volume rm hf-model-weights "perf_reports/" --recursive; then
log "Successfully deleted perf_reports/ from Modal Volume."
else
log "Warning: Failed to delete perf_reports/ from Modal Volume. Manual cleanup may be required."
fi
}
_cleanup_local() {
log "Cleaning up local download directory..."
rm -rf "$LOCAL_DIR"
}
# --- Main flow ---
_download_reports || { _cleanup_local; return 1; }
_upload_dashboard
_upload_perf_summary
_cleanup_modal_volume
_cleanup_local
}
case "$TEST_TYPE" in
"encoder")
log "Running encoder tests..."
MODAL_COMMAND="$MODAL_ENV HF_API_KEY=$HF_API_KEY python3 -m modal run $MODAL_TEST_FILE::run_encoder_tests"
;;
"vae")
log "Running VAE tests..."
MODAL_COMMAND="$MODAL_ENV HF_API_KEY=$HF_API_KEY python3 -m modal run $MODAL_TEST_FILE::run_vae_tests"
;;
"transformer")
log "Running transformer tests..."
MODAL_COMMAND="$MODAL_ENV HF_API_KEY=$HF_API_KEY python3 -m modal run $MODAL_TEST_FILE::run_transformer_tests"
;;
"ssim")
log "Running SSIM tests..."
MODAL_COMMAND="$MODAL_ENV HF_API_KEY=$HF_API_KEY python3 -m modal run $MODAL_SSIM_TEST_FILE::run_ssim_tests"
;;
"training")
log "Running training tests..."
MODAL_COMMAND="$MODAL_ENV WANDB_API_KEY=$WANDB_API_KEY python3 -m modal run $MODAL_TEST_FILE::run_training_tests"
;;
"training_lora")
log "Running LoRA training tests..."
MODAL_COMMAND="$MODAL_ENV WANDB_API_KEY=$WANDB_API_KEY python3 -m modal run $MODAL_TEST_FILE::run_training_lora_tests"
;;
"training_vsa")
log "Running training VSA tests..."
MODAL_COMMAND="$MODAL_ENV WANDB_API_KEY=$WANDB_API_KEY python3 -m modal run $MODAL_TEST_FILE::run_training_tests_VSA"
;;
"kernel_tests")
log "Running kernel tests..."
MODAL_COMMAND="$MODAL_ENV python3 -m modal run $MODAL_TEST_FILE::run_kernel_tests"
;;
"inference_lora")
log "Running LoRA tests..."
MODAL_COMMAND="$MODAL_ENV python3 -m modal run $MODAL_TEST_FILE::run_inference_lora_tests"
;;
"distillation_dmd")
log "Running distillation DMD tests..."
MODAL_COMMAND="$MODAL_ENV WANDB_API_KEY=$WANDB_API_KEY python3 -m modal run $MODAL_TEST_FILE::run_distill_dmd_tests"
;;
# run_inference_tests_vmoba
"self_forcing")
log "Running self-forcing tests..."
MODAL_COMMAND="$MODAL_ENV WANDB_API_KEY=$WANDB_API_KEY python3 -m modal run $MODAL_TEST_FILE::run_self_forcing_tests"
;;
"inference_vmoba")
log "Running V-MoBA inference tests..."
MODAL_COMMAND="$MODAL_ENV python3 -m modal run $MODAL_TEST_FILE::run_inference_tests_vmoba"
;;
"unit_test")
log "Running unit tests..."
MODAL_COMMAND="$MODAL_ENV python3 -m modal run $MODAL_TEST_FILE::run_unit_test"
;;
"lora_extraction")
log "Running LoRA extraction tests..."
MODAL_COMMAND="$MODAL_ENV HF_API_KEY=$HF_API_KEY python3 -m modal run $MODAL_TEST_FILE::run_lora_extraction_tests"
;;
"performance")
log "Running performance tests on Modal..."
MODAL_COMMAND="$MODAL_ENV HF_API_KEY=$HF_API_KEY python3 -m modal run $MODAL_TEST_FILE::run_performance_tests"
POST_RUN_HOOK="upload_performance_artifacts"
;;
"api_server")
log "Running API server integration tests..."
MODAL_COMMAND="$MODAL_ENV HF_API_KEY=$HF_API_KEY python3 -m modal run $MODAL_TEST_FILE::run_api_server_tests"
;;
*)
log "Error: Unknown test type: $TEST_TYPE"
exit 1
;;
esac
log "Executing: $MODAL_COMMAND"
eval "$MODAL_COMMAND"
TEST_EXIT_CODE=$?
if [ $TEST_EXIT_CODE -eq 0 ]; then
log "Modal test completed successfully"
else
log "Error: Modal test failed with exit code: $TEST_EXIT_CODE"
fi
if [ -n "$POST_RUN_HOOK" ]; then
log "Executing post-run hook: $POST_RUN_HOOK"
"$POST_RUN_HOOK"
fi
log "=== Test execution completed with exit code: $TEST_EXIT_CODE ==="
exit $TEST_EXIT_CODE
-53
View File
@@ -1,53 +0,0 @@
#!/bin/bash
set -uo pipefail
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
log "=== Starting pre-commit checks ==="
cd "$(dirname "$0")/../.."
PROJECT_ROOT=$(pwd)
log "Project root: $PROJECT_ROOT"
if ! python3 -m pre_commit --version &> /dev/null; then
log "pre-commit not found, installing..."
if ! command -v uv &> /dev/null; then
log "uv not found, bootstrapping..."
if ! curl -LsSf https://astral.sh/uv/install.sh | sh; then
log "Error: Failed to bootstrap uv via astral.sh installer."
exit 1
fi
export PATH="$HOME/.local/bin:$PATH"
if ! command -v uv &> /dev/null; then
log "Error: uv still not on PATH after bootstrap."
exit 1
fi
fi
# --break-system-packages preserves prior `pip install --user` semantics on PEP 668 agents.
uv pip install --system --break-system-packages pre-commit==4.0.1
if ! python3 -m pre_commit --version &> /dev/null; then
log "Error: Failed to install pre-commit."
exit 1
fi
fi
log "Pre-commit version: $(python3 -m pre_commit --version)"
log "Installing/updating pre-commit hooks..."
python3 -m pre_commit install --install-hooks
log "Running pre-commit checks on all files..."
python3 -m pre_commit run --all-files
PRE_COMMIT_EXIT_CODE=$?
if [ $PRE_COMMIT_EXIT_CODE -eq 0 ]; then
log "Pre-commit checks completed successfully"
else
log "Error: Pre-commit checks failed with exit code: $PRE_COMMIT_EXIT_CODE"
fi
log "=== Pre-commit checks completed with exit code: $PRE_COMMIT_EXIT_CODE ==="
exit $PRE_COMMIT_EXIT_CODE
-29
View File
@@ -1,29 +0,0 @@
name: 🐞 Bug report
description: Create a report to help us reproduce and fix the bug
title: "[Bug] "
labels: ['Bug']
body:
- type: textarea
attributes:
label: Describe the bug
description: A clear and concise description of what the bug is.
validations:
required: true
- type: textarea
attributes:
label: Reproduction
description: |
What command or script did you run? Which **model** are you using?
placeholder: |
A placeholder for the command.
validations:
required: true
- type: textarea
attributes:
label: Environment
description: |
Please share your environment with us. You can run the command **python collect_env.py** and copy-paste its output below.
placeholder: FastVideo version, platform, python version, cuda version...
validations:
required: true
@@ -1,17 +0,0 @@
name: 🚀 Feature request
description: Suggest an idea for this project
title: "[Feature] "
body:
- type: textarea
attributes:
label: Motivation
description: |
A clear and concise description of the motivation of the feature.
validations:
required: true
- type: textarea
attributes:
label: Related resources
description: |
If there is an official code release or third-party implementations, please also provide the information here, which would be very helpful.
-56
View File
@@ -1,56 +0,0 @@
name: 💬 Request for comments (RFC).
description: Ask for feedback on major architectural changes or design choices.
title: "[RFC]: "
labels: ["RFC"]
body:
- type: markdown
attributes:
value: >
#### Please take a look at previous [RFCs](https://github.com/hao-ai-lab/FastVideo/issues?q=label%3ARFC+sort%3Aupdated-desc) for reference.
- type: textarea
attributes:
label: Motivation.
description: >
The motivation of the RFC.
validations:
required: true
- type: textarea
attributes:
label: Proposed Change.
description: >
The proposed change of the RFC.
validations:
required: true
- type: textarea
attributes:
label: Feedback Period.
description: >
The feedback period of the RFC. Usually at least one week.
validations:
required: false
- type: textarea
attributes:
label: CC List.
description: >
The list of people you want to CC.
validations:
required: false
- type: textarea
attributes:
label: Any Other Things.
description: >
Any other things you would like to mention.
validations:
required: false
- type: markdown
attributes:
value: >
Thanks for contributing 🎉!
- type: checkboxes
id: askllm
attributes:
label: Before submitting a new issue...
options:
- label: Make sure you already searched for relevant issues.
required: true
-1
View File
@@ -1 +0,0 @@
blank_issues_enabled: false
-62
View File
@@ -1,62 +0,0 @@
<!--
PR TITLE: Must start with a type tag, e.g.:
[feat] Add new model [bugfix] Fix VAE tiling [refactor] Restructure pipeline
[perf] Optimize kernel [ci] Update tests [docs] Add guide
[misc] Cleanup configs [new-model] Port Flux2
MERGE WORKFLOW:
1. Ensure pre-commit passes and you have at least 1 approval
2. Comment /merge (or add the "ready" label) to enter the Merge Queue
3. Full Test Suite runs automatically on a staging branch → auto-merge on success
ON-DEMAND TESTING (write access required):
/test full — Full Test Suite /test ssim — SSIM regression
/test training — Training pipeline /test encoder — Encoder tests
/test transformer — Transformer tests /test vae — VAE tests
/test kernel — CUDA kernel tests /test unit — Unit tests
See docs/contributing/pull_requests.md for all 17 test commands
-->
## Purpose
<!-- What does this PR do? Link the related issue if applicable. -->
Fixes #
## Changes
<!-- Describe your changes concisely. What approach did you take? -->
-
## Test Plan
<!-- How did you verify your changes? Paste exact commands and output. -->
```bash
# Commands you ran
```
## Test Results
<!-- Paste test output, before/after comparisons, or SSIM scores for model changes. -->
<details>
<summary>Test output</summary>
```
# Paste output here
```
</details>
## Checklist
- [ ] I ran `pre-commit run --all-files` and fixed all issues
- [ ] I added or updated tests for my changes
- [ ] I updated documentation if needed
- [ ] I considered GPU memory impact of my changes
**For model/pipeline changes, also check:**
- [ ] I verified SSIM regression tests pass
- [ ] I updated the support matrix if adding a new model
-316
View File
@@ -1,316 +0,0 @@
merge_protections:
- name: PR merge requirements
if:
- base = main
success_conditions:
- "title~=(?i)^\\[(feat|feature|bugfix|fix|refactor|perf|ci|doc|docs|misc|chore|kernel|new.?model)\\]"
- "#approved-reviews-by>=1"
- check-success~=pre-commit
- check-success=fastcheck-passed
- check-success=full-suite-passed
pull_request_rules:
# ============================================================
# Type labels (from PR title prefix)
# ============================================================
- name: "label type: feat"
conditions:
- "title~=(?i)^\\[(feat|feature)\\]"
- -closed
actions:
label:
add: ["type: feat"]
- name: "label type: bugfix"
conditions:
- "title~=(?i)^\\[(bug)?fix\\]"
- -closed
actions:
label:
add: ["type: bugfix"]
- name: "label type: refactor"
conditions:
- "title~=(?i)^\\[refactor\\]"
- -closed
actions:
label:
add: ["type: refactor"]
- name: "label type: perf"
conditions:
- "title~=(?i)^\\[perf\\]"
- -closed
actions:
label:
add: ["type: perf"]
- name: "label type: ci"
conditions:
- "title~=(?i)^\\[ci\\]"
- -closed
actions:
label:
add: ["type: ci"]
- name: "label type: docs"
conditions:
- "title~=(?i)^\\[(doc|docs)\\]"
- -closed
actions:
label:
add: ["type: docs"]
- name: "label type: misc"
conditions:
- "title~=(?i)^\\[(misc|chore)\\]"
- -closed
actions:
label:
add: ["type: misc"]
- name: "label type: new-model"
conditions:
- "title~=(?i)^\\[new.?model\\]"
- -closed
actions:
label:
add: ["type: new-model"]
# ============================================================
# Scope labels (from changed files)
# ============================================================
- name: "label scope: training"
conditions:
- or:
- files~=^fastvideo/train/
- files~=^fastvideo/training/
- files~=^fastvideo/distillation/
- files~=^examples/train/
- files~=^examples/training/
- files~=^examples/distill/
- -closed
actions:
label:
add: ["scope: training"]
- name: "label scope: inference"
conditions:
- or:
- files~=^fastvideo/pipelines/basic/
- files~=^fastvideo/pipelines/stages/
- files~=^fastvideo/pipelines/samplers/
- files~=^fastvideo/entrypoints/
- files~=^fastvideo/worker/
- files~=^fastvideo/api/sampling_param
- files~=^fastvideo/configs/pipelines/
- files~=^examples/inference/
- -closed
actions:
label:
add: ["scope: inference"]
- name: "label scope: attention"
conditions:
- files~=^fastvideo/attention/
- -closed
actions:
label:
add: ["scope: attention"]
- name: "label scope: kernel"
conditions:
- or:
- files~=^fastvideo-kernel/
- files~=^csrc/
- -closed
actions:
label:
add: ["scope: kernel"]
- name: "label scope: data"
conditions:
- or:
- files~=^fastvideo/dataset/
- files~=^fastvideo/pipelines/preprocess/
- files~=^examples/preprocessing/
- -closed
actions:
label:
add: ["scope: data"]
- name: "label scope: infra"
conditions:
- or:
- files~=^\.github/
- files~=^\.buildkite/
- files~=^fastvideo/tests/
- files~=^docker/
- -closed
actions:
label:
add: ["scope: infra"]
- name: "label scope: distributed"
conditions:
- files~=^fastvideo/distributed/
- -closed
actions:
label:
add: ["scope: distributed"]
- name: "label scope: docs"
conditions:
- files~=^docs/
- -closed
actions:
label:
add: ["scope: docs"]
- name: "label scope: ui"
conditions:
- files~=^ui/
- -closed
actions:
label:
add: ["scope: ui"]
- name: "label scope: model"
conditions:
- or:
- files~=^fastvideo/models/
- files~=^fastvideo/layers/
- files~=^fastvideo/configs/models/
- -closed
actions:
label:
add: ["scope: model"]
# ============================================================
# Pre-commit failure help comment
# ============================================================
- name: comment on pre-commit failure
conditions:
- check-failure~=pre-commit
- -closed
actions:
comment:
message: |
## Pre-commit checks failed
Hi @{{author}}, the pre-commit checks have failed. To fix them locally:
```bash
# Install pre-commit if you haven't already
uv pip install pre-commit
pre-commit install
# Run all checks and auto-fix what's possible
pre-commit run --all-files
```
Common fixes:
- **yapf**: `yapf -i <file>` (formatting)
- **ruff**: `ruff check --fix <file>` (linting)
- **codespell**: `codespell --write-changes <file>` (spelling)
After fixing, commit and push the changes. The checks will re-run automatically.
For future commits, `pre-commit` will run automatically on changed files before each commit.
# ============================================================
# Merge conflict detection
# ============================================================
- name: label conflicting PRs
conditions:
- conflict
- -closed
- label!=stale
actions:
label:
add: [needs-rebase]
comment:
message: |
This PR has merge conflicts with the base branch. Please rebase:
```bash
git fetch origin main
git rebase origin/main
# Resolve any conflicts, then:
git push --force-with-lease
```
- name: remove conflict label when resolved
conditions:
- -conflict
- -closed
- label=needs-rebase
actions:
label:
remove: [needs-rebase]
# ============================================================
# Auto-merge and auto-rebase
# ============================================================
- name: auto-merge when ready and all checks pass
conditions:
- label=ready
- "title~=(?i)^\\[(feat|feature|bugfix|fix|refactor|perf|ci|doc|docs|misc|chore|kernel|new.?model)\\]"
- "#approved-reviews-by>=1"
- check-success~=pre-commit
- check-success=fastcheck-passed
- check-success=full-suite-passed
- -conflict
- -closed
- -draft
actions:
merge:
method: squash
- name: auto-update when ready
conditions:
- label=ready
- "#approved-reviews-by>=1"
- -conflict
- -closed
- -draft
actions:
update: {}
# ============================================================
# PR title format help
# ============================================================
- name: comment on invalid PR title format
conditions:
- -closed
- -draft
- "-title~=(?i)^\\[(feat|feature|bugfix|fix|refactor|perf|ci|doc|docs|misc|chore|kernel|new.?model)\\]"
actions:
comment:
message: |
## ⚠️ PR title format required
Your PR title must start with a type tag in brackets. Examples:
- `[feat] Add new model support`
- `[bugfix] Fix VAE tiling corruption`
- `[refactor] Restructure training pipeline`
- `[perf] Optimize attention kernel`
- `[ci] Update test infrastructure`
- `[docs] Add inference guide`
- `[misc] Clean up configs`
- `[new-model] Port Flux2 to FastVideo`
Valid tags: `feat`, `feature`, `bugfix`, `fix`, `refactor`, `perf`, `ci`, `doc`, `docs`, `misc`, `chore`, `kernel`, `new-model`
Please update your PR title and the merge protection check will pass automatically.
merge_protections_settings:
reporting_method: check-runs
-106
View File
@@ -1,106 +0,0 @@
name: Build Image Template
on:
workflow_call:
inputs:
python_version:
required: true
type: string
dockerfile_path:
required: true
type: string
tag_suffix:
required: true
type: string
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Free up disk space
run: |
# Display initial space
echo "Initial disk space:"
df -h
# Remove large directories directly
sudo rm -rf /usr/share/dotnet
sudo rm -rf /usr/local/lib/android
sudo rm -rf /opt/ghc
sudo rm -rf /usr/local/share/boost
sudo rm -rf /usr/share/swift
sudo rm -rf /usr/local/lib/node_modules
sudo rm -rf /usr/local/share/powershell
sudo rm -rf /usr/share/rust
sudo rm -rf /usr/local/.ghcup
# Remove cached files
sudo rm -rf /var/lib/apt/lists/*
sudo rm -rf /var/cache/apt/archives/*
# Clean Docker
docker system prune -af --volumes
# Display available space after cleanup
echo "Disk space after cleanup:"
df -h
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Prepare tags
id: prepare-tags
run: |
SHORT_SHA=$(echo ${{ github.sha }} | cut -c1-7)
TAGS="type=raw,value=${{ inputs.tag_suffix }}-latest"
TAGS="${TAGS}\ntype=raw,value=${{ inputs.tag_suffix }}-sha-${SHORT_SHA}"
# Set Python 3.10 as the default image
if [[ "${{ inputs.python_version }}" == "3.10" ]]; then
TAGS="${TAGS}\ntype=raw,value=latest"
fi
{
echo "tags<<EOF"
echo -e "$TAGS"
echo "EOF"
} >> $GITHUB_OUTPUT
- name: Extract metadata for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}/fastvideo-dev
tags: ${{ steps.prepare-tags.outputs.tags }}
- name: Build and push Docker image
id: build-push
uses: docker/build-push-action@v6
with:
context: .
file: ${{ inputs.dockerfile_path }}
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Success message
run: |
echo "✅ Python ${{ inputs.python_version }} image successfully built and pushed to ghcr.io/${{ github.repository }}/fastvideo-dev:${{ inputs.tag_suffix }}-latest"
echo "To run tests with this image, manually trigger the 'Run Tests' workflow."
-80
View File
@@ -1,80 +0,0 @@
name: Aggregate Test Status
on:
status:
permissions:
statuses: write
jobs:
aggregate:
if: >-
github.event.context == 'direct-test-completed'
&& github.event.state == 'success'
runs-on: ubuntu-latest
steps:
- name: Check and update aggregate status
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
const sha = context.payload.sha;
const { data } = await github.rest.repos.getCombinedStatusForRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: sha,
per_page: 100,
});
const bkStatuses = data.statuses.filter(
s => s.context.startsWith('buildkite/ci/')
);
const FASTCHECK_PREFIX = 'buildkite/ci/microscope-';
const FULL_SUITE_PREFIXES = [
'buildkite/ci/test-tube-',
'buildkite/ci/bar-chart-',
];
const fastcheck = bkStatuses.filter(
s => s.context.startsWith(FASTCHECK_PREFIX)
);
const fullSuite = bkStatuses.filter(
s => FULL_SUITE_PREFIXES.some(p => s.context.startsWith(p))
);
if (
fastcheck.length > 0
&& fastcheck.every(s => s.state === 'success')
) {
core.info(
`All ${fastcheck.length} fastcheck tests passed — updating fastcheck-passed`
);
await github.rest.repos.createCommitStatus({
owner: context.repo.owner,
repo: context.repo.repo,
sha,
state: 'success',
context: 'fastcheck-passed',
description:
`All ${fastcheck.length} fastcheck tests passed`,
});
}
if (
fullSuite.length > 0
&& fullSuite.every(s => s.state === 'success')
) {
core.info(
`All ${fullSuite.length} full suite tests passed — updating full-suite-passed`
);
await github.rest.repos.createCommitStatus({
owner: context.repo.owner,
repo: context.repo.repo,
sha,
state: 'success',
context: 'full-suite-passed',
description:
`All ${fullSuite.length} full suite tests passed`,
});
}
-32
View File
@@ -1,32 +0,0 @@
name: pre-commit
on:
pull_request:
branches: [main]
workflow_call:
inputs:
ref:
description: 'Git ref to checkout (defaults to github.ref)'
required: false
type: string
permissions:
contents: read
jobs:
pre-commit:
if: github.event_name == 'workflow_call' || github.event.pull_request.draft != true
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.ref || '' }}
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: echo "::add-matcher::.github/workflows/matchers/actionlint.json"
- run: echo "::add-matcher::.github/workflows/matchers/mypy.json"
- run: echo "::add-matcher::.github/workflows/matchers/ruff.json"
- uses: pre-commit/action@v3.0.1
with:
extra_args: --all-files --hook-stage manual
-271
View File
@@ -1,271 +0,0 @@
name: Slash Commands
on:
issue_comment:
types: [created]
permissions:
contents: read
pull-requests: write
statuses: write
jobs:
handle-merge:
if: >-
github.event.issue.pull_request != null
&& startsWith(github.event.comment.body, '/merge')
runs-on: ubuntu-latest
steps:
- name: Check write permission
id: perm
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
const { data: perm } = await github.rest.repos.getCollaboratorPermissionLevel({
owner: context.repo.owner,
repo: context.repo.repo,
username: context.payload.comment.user.login,
});
const hasWrite = ['admin', 'write'].includes(perm.permission);
if (!hasWrite) {
core.setFailed(`User ${context.payload.comment.user.login} lacks write permission (has: ${perm.permission}).`);
}
core.setOutput('has_write', String(hasWrite));
- name: Add ready label and react
id: label
if: steps.perm.outputs.has_write == 'true'
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
const prNumber = context.payload.issue.number;
try { await github.rest.issues.removeLabel({ owner, repo, issue_number: prNumber, name: 'ready' }); } catch {}
await github.rest.issues.addLabels({ owner, repo, issue_number: prNumber, labels: ['ready'] });
await github.rest.reactions.createForIssueComment({
owner, repo,
comment_id: context.payload.comment.id,
content: 'rocket',
});
const { data: pr } = await github.rest.pulls.get({ owner, repo, pull_number: prNumber });
core.setOutput('pr_sha', pr.head.sha);
core.setOutput('pr_branch', pr.head.ref);
core.setOutput('pr_number', String(prNumber));
- name: Trigger Full Suite
if: steps.perm.outputs.has_write == 'true'
env:
BUILDKITE_API_TOKEN: ${{ secrets.BUILDKITE_API_TOKEN }}
PR_SHA: ${{ steps.label.outputs.pr_sha }}
PR_BRANCH: ${{ steps.label.outputs.pr_branch }}
PR_NUMBER: ${{ steps.label.outputs.pr_number }}
BK_ORG: ${{ vars.BUILDKITE_ORG_SLUG }}
BK_PIPELINE: ${{ vars.BUILDKITE_PIPELINE_SLUG }}
run: |
curl -sS --fail-with-body -X POST \
"https://api.buildkite.com/v2/organizations/${BK_ORG}/pipelines/${BK_PIPELINE}/builds" \
-H "Authorization: Bearer $BUILDKITE_API_TOKEN" \
-H "Content-Type: application/json" \
--data-raw "$(jq -n \
--arg commit "$PR_SHA" \
--arg branch "$PR_BRANCH" \
--arg message "Full Suite for PR #${PR_NUMBER} (via /merge)" \
--argjson pr_id "$PR_NUMBER" \
'{
commit: $commit,
branch: $branch,
message: $message,
ignore_pipeline_branch_filters: true,
pull_request_id: $pr_id,
pull_request_base_branch: "main",
env: {
TEST_SCOPE: "full",
FULL_SUITE: "true",
PR_NUMBER: ($pr_id | tostring)
}
}')"
parse-command:
if: >-
github.event.issue.pull_request != null
&& startsWith(github.event.comment.body, '/test')
runs-on: ubuntu-latest
outputs:
test_type: ${{ steps.parse.outputs.test_type }}
test_scope: ${{ steps.parse.outputs.test_scope }}
full_suite: ${{ steps.parse.outputs.full_suite }}
pr_sha: ${{ steps.pr.outputs.sha }}
pr_branch: ${{ steps.pr.outputs.branch }}
has_write: ${{ steps.perm.outputs.has_write }}
steps:
- name: Check write permission
id: perm
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
const { data: perm } = await github.rest.repos.getCollaboratorPermissionLevel({
owner: context.repo.owner,
repo: context.repo.repo,
username: context.payload.comment.user.login,
});
const hasWrite = ['admin', 'write'].includes(perm.permission);
core.setOutput('has_write', String(hasWrite));
if (!hasWrite) {
core.info(`User ${context.payload.comment.user.login} lacks write permission — ignoring.`);
}
- name: Parse /test command
id: parse
if: steps.perm.outputs.has_write == 'true'
shell: bash
env:
COMMENT: ${{ github.event.comment.body }}
run: |
set -euo pipefail
TEST_NAME=$(echo "$COMMENT" | grep -oP '(?<=/test\s)\S+' | head -1 || true)
VALID="encoder vae transformer kernel unit ssim training lora-inference lora-training distillation self-forcing vsa vmoba performance api full fastcheck pre-commit"
if [ -z "$TEST_NAME" ] || ! echo "$VALID" | grep -qw "$TEST_NAME"; then
echo "Unknown test: '$TEST_NAME'. Valid: $VALID"
exit 1
fi
declare -A MAP=(
[encoder]=encoder [vae]=vae [transformer]=transformer
[kernel]=kernel_tests [unit]=unit_test
[ssim]=ssim [training]=training
[lora-inference]=inference_lora [lora-training]=training_lora
[distillation]=distillation_dmd [self-forcing]=self_forcing
[vsa]=training_vsa [vmoba]=inference_vmoba
[performance]=performance [api]=api_server
)
if [ "$TEST_NAME" = "full" ]; then
{
echo "test_type=all"
echo "test_scope=full"
echo "full_suite=true"
} >> "$GITHUB_OUTPUT"
elif [ "$TEST_NAME" = "fastcheck" ]; then
{
echo "test_type=fastcheck"
echo "test_scope=fastcheck"
echo "full_suite=false"
} >> "$GITHUB_OUTPUT"
elif [ "$TEST_NAME" = "pre-commit" ]; then
{
echo "test_type="
echo "test_scope=precommit"
echo "full_suite=false"
} >> "$GITHUB_OUTPUT"
else
{
echo "test_type=${MAP[$TEST_NAME]}"
echo "test_scope=direct"
echo "full_suite=false"
} >> "$GITHUB_OUTPUT"
fi
- name: Get PR details
id: pr
if: steps.perm.outputs.has_write == 'true'
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
const { data: pr } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.payload.issue.number,
});
core.setOutput('sha', pr.head.sha);
core.setOutput('branch', pr.head.ref);
- name: React to comment
if: steps.perm.outputs.has_write == 'true'
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
await github.rest.reactions.createForIssueComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: context.payload.comment.id,
content: 'rocket',
});
pre-commit:
needs: parse-command
if: >-
needs.parse-command.outputs.has_write == 'true'
&& needs.parse-command.outputs.test_scope == 'precommit'
uses: ./.github/workflows/ci-precommit.yml
with:
ref: refs/pull/${{ github.event.issue.number }}/merge
post-precommit-status:
needs: [parse-command, pre-commit]
if: always() && needs.parse-command.outputs.test_scope == 'precommit'
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
env:
PR_SHA: ${{ needs.parse-command.outputs.pr_sha }}
RESULT: ${{ needs.pre-commit.result }}
with:
script: |
const state = process.env.RESULT === 'success' ? 'success' : 'failure';
await github.rest.repos.createCommitStatus({
owner: context.repo.owner,
repo: context.repo.repo,
sha: process.env.PR_SHA,
state,
context: 'pre-commit',
description: `Triggered via /test pre-commit (${state})`,
});
trigger-buildkite:
needs: parse-command
if: >-
needs.parse-command.outputs.has_write == 'true'
&& needs.parse-command.outputs.test_type != ''
runs-on: ubuntu-latest
steps:
- name: Trigger Buildkite
env:
BUILDKITE_API_TOKEN: ${{ secrets.BUILDKITE_API_TOKEN }}
PR_SHA: ${{ needs.parse-command.outputs.pr_sha }}
PR_BRANCH: ${{ needs.parse-command.outputs.pr_branch }}
PR_NUMBER: ${{ github.event.issue.number }}
TEST_SCOPE: ${{ needs.parse-command.outputs.test_scope }}
FULL_SUITE: ${{ needs.parse-command.outputs.full_suite }}
TEST_TYPE: ${{ needs.parse-command.outputs.test_type }}
BK_ORG: ${{ vars.BUILDKITE_ORG_SLUG }}
BK_PIPELINE: ${{ vars.BUILDKITE_PIPELINE_SLUG }}
run: |
curl -sS --fail-with-body -X POST \
"https://api.buildkite.com/v2/organizations/${BK_ORG}/pipelines/${BK_PIPELINE}/builds" \
-H "Authorization: Bearer $BUILDKITE_API_TOKEN" \
-H "Content-Type: application/json" \
--data-raw "$(jq -n \
--arg commit "$PR_SHA" \
--arg branch "$PR_BRANCH" \
--arg message "/test ${TEST_TYPE} on PR #${PR_NUMBER}" \
--argjson pr_id "$PR_NUMBER" \
--arg test_scope "$TEST_SCOPE" \
--arg full_suite "$FULL_SUITE" \
--arg test_type "$TEST_TYPE" \
--arg pr_number "$PR_NUMBER" \
'{
commit: $commit,
branch: $branch,
message: $message,
ignore_pipeline_branch_filters: true,
pull_request_id: $pr_id,
pull_request_base_branch: "main",
env: {
TEST_SCOPE: $test_scope,
FULL_SUITE: $full_suite,
TEST_TYPE: $test_type,
PR_NUMBER: $pr_number
}
}')"
@@ -1,83 +0,0 @@
name: Trigger Full Suite
on:
pull_request_target:
types: [labeled, synchronize]
permissions:
contents: read
pull-requests: read
concurrency:
group: full-suite-${{ github.event.pull_request.number }}
cancel-in-progress: false
jobs:
trigger:
if: >-
(github.event.action == 'labeled' && github.event.label.name == 'ready')
|| github.event.action == 'synchronize'
runs-on: ubuntu-latest
steps:
- name: Check ready label
id: check
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
const { data: pr } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.payload.pull_request.number,
});
const hasReady = pr.labels.some(l => l.name === 'ready');
core.setOutput('has_ready', String(hasReady));
if (!hasReady) core.info('No ready label — skipping Full Suite trigger.');
- name: Cancel previous Buildkite builds
if: steps.check.outputs.has_ready == 'true'
env:
BUILDKITE_API_TOKEN: ${{ secrets.BUILDKITE_API_TOKEN }}
PR_BRANCH: ${{ github.event.pull_request.head.ref }}
run: |
# Find running builds for this branch with TEST_SCOPE=full and cancel them
builds=$(curl -sS -H "Authorization: Bearer $BUILDKITE_API_TOKEN" \
"https://api.buildkite.com/v2/organizations/${{ vars.BUILDKITE_ORG_SLUG }}/pipelines/${{ vars.BUILDKITE_PIPELINE_SLUG }}/builds?branch=${PR_BRANCH}&state=running,scheduled" \
| jq -r '.[] | select(try (.env.TEST_SCOPE == "full") catch false) | .number')
for build_num in $builds; do
echo "Cancelling Buildkite build #$build_num"
curl -sS -X PUT -H "Authorization: Bearer $BUILDKITE_API_TOKEN" \
"https://api.buildkite.com/v2/organizations/${{ vars.BUILDKITE_ORG_SLUG }}/pipelines/${{ vars.BUILDKITE_PIPELINE_SLUG }}/builds/${build_num}/cancel"
done
- name: Trigger Buildkite Full Suite
if: steps.check.outputs.has_ready == 'true'
env:
BUILDKITE_API_TOKEN: ${{ secrets.BUILDKITE_API_TOKEN }}
PR_SHA: ${{ github.event.pull_request.head.sha }}
PR_BRANCH: ${{ github.event.pull_request.head.ref }}
PR_NUMBER: ${{ github.event.pull_request.number }}
BK_ORG: ${{ vars.BUILDKITE_ORG_SLUG }}
BK_PIPELINE: ${{ vars.BUILDKITE_PIPELINE_SLUG }}
run: |
curl -sS --fail-with-body -X POST \
"https://api.buildkite.com/v2/organizations/${BK_ORG}/pipelines/${BK_PIPELINE}/builds" \
-H "Authorization: Bearer $BUILDKITE_API_TOKEN" \
-H "Content-Type: application/json" \
--data-raw "$(jq -n \
--arg commit "$PR_SHA" \
--arg branch "$PR_BRANCH" \
--arg message "Full Suite for PR #${PR_NUMBER}" \
--argjson pr_id "$PR_NUMBER" \
'{
commit: $commit,
branch: $branch,
message: $message,
ignore_pipeline_branch_filters: true,
pull_request_id: $pr_id,
pull_request_base_branch: "main",
env: {
TEST_SCOPE: "full",
FULL_SUITE: "true",
PR_NUMBER: ($pr_id | tostring)
}
}')"
@@ -1,65 +0,0 @@
name: Auto-Label Issues
on:
issues:
types: [opened, edited]
permissions:
issues: write
jobs:
label-issues:
if: github.repository == 'hao-ai-lab/FastVideo'
runs-on: ubuntu-latest
steps:
- name: Label by keywords
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
script: |
const title = context.payload.issue.title.toLowerCase();
const body = (context.payload.issue.body || '').toLowerCase();
const text = title + ' ' + body;
const labels = [];
const rules = [
// scope labels (shared with PR labeling via Mergify)
// Mapping: label → repo directories
// scope: training → fastvideo/train/, fastvideo/training/, fastvideo/distillation/
// scope: inference → fastvideo/pipelines/, fastvideo/entrypoints/, fastvideo/worker/
// scope: attention → fastvideo/attention/
// scope: kernel → fastvideo-kernel/, csrc/
// scope: model → fastvideo/models/, fastvideo/layers/, fastvideo/configs/models/
// scope: data → fastvideo/dataset/, fastvideo/pipelines/preprocess/
// scope: distributed → fastvideo/distributed/
// scope: docs → docs/
{ keywords: ['training', 'finetune', 'fine-tune', 'lora', 'fsdp', 'distill'], label: 'scope: training' },
{ keywords: ['inference', 'generate', 'pipeline', 'slow', 'latency'], label: 'scope: inference' },
{ keywords: ['attention', 'vsa', 'flash', 'sta', 'vmoba', 'sparse attn'], label: 'scope: attention' },
{ keywords: ['kernel', 'csrc', 'cuda kernel', 'thunderkittens'], label: 'scope: kernel' },
{ keywords: ['wan', 'hunyuan', 'mochi', 'ltx', 'cogvideo', 'flux', 'sd3', 'cosmos'], label: 'scope: model' },
{ keywords: ['dataset', 'dataloader', 'preprocessing', 'preprocess'], label: 'scope: data' },
{ keywords: ['distributed', 'sequence parallel', 'fsdp', 'tensor parallel', 'multi-node', 'multi-gpu'], label: 'scope: distributed' },
{ keywords: ['docs', 'documentation', 'tutorial', 'example'], label: 'scope: docs' },
// issue-only labels (cross-module, no single repo directory)
{ keywords: ['install', 'setup', 'pip', 'cuda', 'uv ', 'import error', 'modulenotfound'], label: 'installation' },
{ keywords: ['memory', 'oom', 'out of memory', 'gpu memory', 'vram'], label: 'performance' },
{ keywords: ['windows', 'macos', 'mac os', 'apple', 'mps', 'rocm', 'amd', 'npu'], label: 'platform' },
];
for (const rule of rules) {
if (rule.keywords.some(kw => text.includes(kw))) {
labels.push(rule.label);
}
}
if (labels.length > 0) {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.issue.number,
labels: labels,
});
console.log(`Added labels: ${labels.join(', ')}`);
} else {
console.log('No keyword matches found');
}
-51
View File
@@ -1,51 +0,0 @@
name: Close Stale Issues and PRs
on:
schedule:
# Daily at 1:30 AM UTC
- cron: '30 1 * * *'
jobs:
stale:
if: github.repository == 'hao-ai-lab/FastVideo'
permissions:
issues: write
pull-requests: write
actions: write
runs-on: ubuntu-latest
steps:
- uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # v10.1.1
with:
operations-per-run: 500
exempt-draft-pr: true
exempt-issue-labels: 'keep-open,pinned,security,Bug,RFC'
exempt-pr-labels: 'keep-open,pinned'
labels-to-add-when-unstale: 'unstale'
labels-to-remove-when-stale: 'unstale'
days-before-issue-stale: 90
days-before-issue-close: 30
stale-issue-label: 'stale'
stale-issue-message: >
This issue has been automatically marked as stale because it has not
had any activity within 90 days. It will be automatically closed if
no further activity occurs within 30 days. Leave a comment if you
feel this issue should remain open. Thank you!
close-issue-message: >
This issue has been automatically closed due to inactivity. Please
feel free to reopen if you feel it is still relevant. Thank you!
days-before-pr-stale: 60
days-before-pr-close: 14
stale-pr-label: 'stale'
stale-pr-message: >
This pull request has been automatically marked as stale because it
has not had any activity within 60 days. It will be automatically
closed if no further activity occurs within 14 days. Leave a comment
if you feel this pull request should remain open. Thank you!
close-pr-message: >
This pull request has been automatically closed due to inactivity.
Please feel free to reopen if you intend to continue working on it.
Thank you!
-56
View File
@@ -1,56 +0,0 @@
name: Welcome First-Time Contributors
on:
issues:
types: [opened]
pull_request_target:
types: [opened]
permissions:
issues: write
pull-requests: write
jobs:
welcome:
if: github.repository == 'hao-ai-lab/FastVideo'
runs-on: ubuntu-latest
steps:
- uses: actions/first-interaction@34f15e814fe48ac9312ccf29db4e74fa767cbab7 # v1.3.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
issue-message: |
Welcome to FastVideo! Thanks for opening your first issue.
To help us investigate, please include:
- **FastVideo version**: `pip show fastvideo`
- **GPU**: `nvidia-smi` output (GPU model, driver, CUDA version)
- **Python version**: `python --version`
- **OS**: e.g., Ubuntu 22.04
If this is a bug, a minimal reproduction script helps us fix it faster.
Useful links:
- [Documentation](https://hao-ai-lab.github.io/FastVideo)
- [Contributing Guide](https://hao-ai-lab.github.io/FastVideo/contributing/overview/)
- [Slack](https://join.slack.com/t/fastvideo/shared_invite/zt-3f4lao1uq-u~Ipx6Lt4J27AlD2y~IdLQ)
pr-message: |
Welcome to FastVideo! Thanks for your first pull request.
**How our CI works:**
PRs run a two-tier CI system:
1. **Pre-commit** — formatting (yapf), linting (ruff), type checking (mypy). Runs immediately on every PR.
2. **Fastcheck** — core GPU tests (encoders, VAEs, transformers, kernels, unit tests). Runs automatically via Buildkite on relevant file changes (~10-15 min).
3. **Full Suite** — integration tests, training pipelines, SSIM regression. Runs only when a reviewer adds the `ready` label.
**Before your PR is reviewed:**
- [ ] `pre-commit run --all-files` passes locally
- [ ] You've added or updated tests for your changes
- [ ] The PR description explains what and why
If pre-commit fails, a bot comment will explain how to fix it. Fastcheck and Full Suite results appear in the Checks section below.
**Useful links:**
- [Contributing Guide](https://hao-ai-lab.github.io/FastVideo/contributing/overview/)
- [Development Roadmap](https://github.com/hao-ai-lab/FastVideo/issues/899)
- [Slack](https://join.slack.com/t/fastvideo/shared_invite/zt-3f4lao1uq-u~Ipx6Lt4J27AlD2y~IdLQ)
-67
View File
@@ -1,67 +0,0 @@
name: Build and Push Docker Images
on:
workflow_dispatch:
inputs:
python_3_10:
description: 'Build Python 3.10 image'
required: false
default: false
type: boolean
python_3_11:
description: 'Build Python 3.11 image'
required: false
default: false
type: boolean
python_3_12:
description: 'Build Python 3.12 image'
required: false
default: false
type: boolean
python_3_12_cuda_12_9:
description: 'Build Python 3.12 image Cuda 12.9'
required: false
default: false
type: boolean
permissions:
contents: read
packages: write
jobs:
build-python-3-10:
if: ${{ github.event.inputs.python_3_10 == 'true' }}
uses: ./.github/workflows/_template-build-image.yml
with:
python_version: '3.10'
dockerfile_path: docker/Dockerfile.python3.10
tag_suffix: py3.10
secrets: inherit
build-python-3-11:
if: ${{ github.event.inputs.python_3_11 == 'true' }}
uses: ./.github/workflows/_template-build-image.yml
with:
python_version: '3.11'
dockerfile_path: docker/Dockerfile.python3.11
tag_suffix: py3.11
secrets: inherit
build-python-3-12:
if: ${{ github.event.inputs.python_3_12 == 'true' }}
uses: ./.github/workflows/_template-build-image.yml
with:
python_version: '3.12'
dockerfile_path: docker/Dockerfile.python3.12
tag_suffix: py3.12
secrets: inherit
build-python-3-12-cuda-12-9:
if: ${{ github.event.inputs.python_3_12_cuda_12_9 == 'true' }}
uses: ./.github/workflows/_template-build-image.yml
with:
python_version: '3.12'
dockerfile_path: docker/Dockerfile.python3.12.cuda12.9.1
tag_suffix: py3.12-cuda12.9.1
secrets: inherit
-73
View File
@@ -1,73 +0,0 @@
name: Deploy Documentation
on:
push:
branches: [ main ]
paths:
- 'docs/**'
- 'mkdocs.yml'
- 'requirements-mkdocs.txt'
- '.github/workflows/infra-docs.yml'
pull_request:
branches: [ main ]
paths:
- 'docs/**'
- 'mkdocs.yml'
- 'requirements-mkdocs.txt'
- '.github/workflows/infra-docs.yml'
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install uv
uses: astral-sh/setup-uv@v3
- name: Install dependencies
run: uv pip install --system -r requirements-mkdocs.txt
- name: Setup Pages
uses: actions/configure-pages@v4
- name: Generate docs examples
run: python docs/generate_examples.py
- name: Check docs links
run: python scripts/check_docs_links.py
- name: Build documentation
run: mkdocs build
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./site
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/main'
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
@@ -1,17 +0,0 @@
{
"problemMatcher": [
{
"owner": "actionlint",
"pattern": [
{
"regexp": "^(?:\\x1b\\[\\d+m)?(.+?)(?:\\x1b\\[\\d+m)*:(?:\\x1b\\[\\d+m)*(\\d+)(?:\\x1b\\[\\d+m)*:(?:\\x1b\\[\\d+m)*(\\d+)(?:\\x1b\\[\\d+m)*: (?:\\x1b\\[\\d+m)*(.+?)(?:\\x1b\\[\\d+m)* \\[(.+?)\\]$",
"file": 1,
"line": 2,
"column": 3,
"message": 4,
"code": 5
}
]
}
]
}
-16
View File
@@ -1,16 +0,0 @@
{
"problemMatcher": [
{
"owner": "mypy",
"pattern": [
{
"regexp": "^(.+):(\\d+):\\s(error|warning):\\s(.+)$",
"file": 1,
"line": 2,
"severity": 3,
"message": 4
}
]
}
]
}
-17
View File
@@ -1,17 +0,0 @@
{
"problemMatcher": [
{
"owner": "ruff",
"pattern": [
{
"regexp": "^(.+):(\\d+):(\\d+): (\\w+) (.+)$",
"file": 1,
"line": 2,
"column": 3,
"code": 4,
"message": 5
}
]
}
]
}
-28
View File
@@ -1,28 +0,0 @@
name: Publish to Comfy registry
on:
workflow_dispatch:
push:
branches:
- main
- master
paths:
- "pyproject.toml"
permissions:
issues: write
jobs:
publish-node:
name: Publish Custom Node to registry
runs-on: ubuntu-latest
if: ${{ github.repository_owner == 'hao-ai-lab' }}
steps:
- name: Check out code
uses: actions/checkout@v4
with:
submodules: true
- name: Publish Custom Node
uses: Comfy-Org/publish-node-action@v1
with:
## Add your own personal access token to your Github Repository secrets and reference it here.
personal_access_token: ${{ secrets.REGISTRY_ACCESS_TOKEN }}
-72
View File
@@ -1,72 +0,0 @@
name: Publish FastVideo to PyPI on Version Change
on:
push:
branches:
- main
paths:
- 'pyproject.toml' # Trigger when pyproject.toml changes
workflow_dispatch:
jobs:
check-version-change:
runs-on: ubuntu-latest
outputs:
version-changed: ${{ steps.check-version.outputs.changed }}
new-version: ${{ steps.check-version.outputs.new-version }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Check if version changed
id: check-version
run: |
# Get current commit's version
NEW_VERSION=$(grep -oP "version\\s*=\\s*\"\\K[^\"]+\"" pyproject.toml)
echo "New version: $NEW_VERSION"
# Get previous version from git history
OLD_VERSION=$(git show HEAD~1:./pyproject.toml | grep -oP "version\\s*=\\s*\"\\K[^\"]+\"" || echo "0.0.0")
echo "Old version: $OLD_VERSION"
if [ "$NEW_VERSION" != "$OLD_VERSION" ]; then
echo "Version changed from $OLD_VERSION to $NEW_VERSION"
echo "changed=true" >> $GITHUB_OUTPUT
echo "new-version=$NEW_VERSION" >> $GITHUB_OUTPUT
else
echo "Version did not change"
echo "changed=false" >> $GITHUB_OUTPUT
fi
build-publish-main:
needs: check-version-change
if: ${{ needs.check-version-change.outputs.version-changed == 'true' || github.event_name == 'workflow_dispatch' }}
runs-on: ubuntu-latest
permissions:
id-token: write # Needed for OIDC Trusted Publishing
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Install uv
uses: astral-sh/setup-uv@v3
- name: Install build dependencies
run: uv pip install --system build twine wheel
- name: Build package
run: |
python -m build
- name: Publish release distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: dist/
-230
View File
@@ -1,230 +0,0 @@
name: Publish FastVideo Kernel to PyPI on Version Change
on:
push:
branches:
- main
paths:
- "fastvideo-kernel/pyproject.toml"
workflow_dispatch:
jobs:
check-version-change:
runs-on: ubuntu-latest
outputs:
version-changed: ${{ steps.check-version.outputs.changed }}
new-version: ${{ steps.check-version.outputs.new-version }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Check if version changed
id: check-version
run: |
cd fastvideo-kernel
# Get current commit's version from pyproject.toml
# Use ^ to match start of line to avoid matching minimum-version
NEW_VERSION=$(grep -oP '^version\s*=\s*"\K[^"]+' pyproject.toml)
echo "New version: $NEW_VERSION"
# Get previous version from git history
# Note: git show expects path relative to repo root
OLD_VERSION=$(git show HEAD~1:fastvideo-kernel/pyproject.toml | grep -oP '^version\s*=\s*"\K[^"]+' || echo "0.0.0")
echo "Old version: $OLD_VERSION"
if [ "$NEW_VERSION" != "$OLD_VERSION" ]; then
echo "Version changed from $OLD_VERSION to $NEW_VERSION"
echo "changed=true" >> "$GITHUB_OUTPUT"
echo "new-version=$NEW_VERSION" >> "$GITHUB_OUTPUT"
else
echo "Version did not change"
echo "changed=false" >> "$GITHUB_OUTPUT"
fi
build_wheels:
name: Build Wheel
needs: check-version-change
if: ${{ needs.check-version-change.outputs.version-changed == 'true' || github.event_name == 'workflow_dispatch' }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04]
python-version: ['3.10', '3.11', '3.12']
torch-cuda:
# - torch-version: '2.5.1'
# cuda-version: '12.4.1'
# torch-cuda-short: 'cu124'
# - torch-version: '2.6.0'
# cuda-version: '12.6.3'
# torch-cuda-short: 'cu126'
# - torch-version: '2.7.1'
# cuda-version: '12.8.0'
# torch-cuda-short: 'cu128'
# - torch-version: '2.9.1'
# cuda-version: '12.8.0'
# torch-cuda-short: 'cu128'
- torch-version: '2.10.0'
cuda-version: '12.8.0'
torch-cuda-short: 'cu128'
steps:
- name: Free up disk space
run: |
echo "Initial disk space:"
df -h
# Remove large directories
sudo rm -rf /usr/share/dotnet
sudo rm -rf /usr/local/lib/android
sudo rm -rf /opt/ghc
sudo rm -rf /usr/local/share/boost
sudo rm -rf /usr/share/swift
sudo rm -rf /usr/local/lib/node_modules
sudo rm -rf /usr/local/share/powershell
sudo rm -rf /usr/share/rust
sudo rm -rf /usr/local/.ghcup
# Remove cached files
sudo rm -rf /var/lib/apt/lists/*
sudo rm -rf /var/cache/apt/archives/*
echo "Disk space after cleanup:"
df -h
- name: Checkout
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install CUDA ${{ matrix.torch-cuda.cuda-version }}
uses: Jimver/cuda-toolkit@v0.2.21
id: cuda-toolkit
with:
cuda: ${{ matrix.torch-cuda.cuda-version }}
linux-local-args: '["--toolkit"]'
method: 'network'
- name: Install dependencies (GCC, Clang, CUDA Paths, Git)
run: |
sudo apt update
sudo apt install -y git patchelf gcc-11 g++-11 clang-11
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 100 --slave /usr/bin/g++ g++ /usr/bin/g++-11
# Allow Git to Access Safe Directory
git config --global --add safe.directory /__w/FastVideo/FastVideo
# Set CUDA environment variables
export CUDA_HOME=/usr/local/cuda-${{ matrix.torch-cuda.cuda-version }}
export PATH=${CUDA_HOME}/bin:${PATH}
export LD_LIBRARY_PATH=${CUDA_HOME}/lib64:$LD_LIBRARY_PATH
# Verify installation
gcc --version
g++ --version
clang-11 --version
nvcc --version
- name: Install uv
uses: astral-sh/setup-uv@v3
- name: Install PyTorch ${{ matrix.torch-cuda.torch-version }}+cu${{ matrix.torch-cuda.cuda-version }}
run: |
uv pip install --system typing-extensions==4.12.2
uv pip install --system --no-cache-dir torch==${{ matrix.torch-cuda.torch-version }} --index-url https://download.pytorch.org/whl/${{matrix.torch-cuda.torch-cuda-short}}
nvcc --version
python --version
python -c "import torch; print('PyTorch:', torch.__version__)"
python -c "import torch; print('CUDA:', torch.version.cuda)"
python -c "from torch.utils import cpp_extension; print (cpp_extension.CUDA_HOME)"
- name: Build wheel
run: |
export PYTHONPATH=$GITHUB_WORKSPACE:$PYTHONPATH
uv pip install --system setuptools ninja packaging wheel triton scikit-build-core cmake build
cd fastvideo-kernel
git submodule update --init --recursive # Ensure ThunderKittens submodule is initialized
# Release builds are produced on GPU-less runners, so force-enable TK and target Hopper.
export TORCH_CUDA_ARCH_LIST="9.0a"
export CMAKE_ARGS="${CMAKE_ARGS:-} -DFASTVIDEO_KERNEL_BUILD_TK=ON -DCMAKE_CUDA_ARCHITECTURES=90a"
# Build standard wheel (no local version suffix) for PyPI
python -m build --wheel --outdir dist
# Fix the wheel to be manylinux compliant
uv pip install --system auditwheel
# Point auditwheel at torch libs, but do not vendor them into the wheel.
TORCH_LIB_DIR=$(python - <<'PY'
import os
import torch
print(os.path.join(os.path.dirname(torch.__file__), "lib"))
PY
)
export LD_LIBRARY_PATH="${TORCH_LIB_DIR}:${LD_LIBRARY_PATH}"
# Target manylinux_2_35 (Ubuntu 22.04 native)
auditwheel repair dist/*.whl --plat manylinux_2_35_x86_64 -w fixed_dist \
--exclude libtorch_cuda.so \
--exclude libtorch_cpu.so \
--exclude libtorch.so \
--exclude libc10.so \
--exclude libc10_cuda.so \
--exclude libtorch_python.so
# Move fixed wheels back to dist for upload consistency
rm dist/*.whl
mv fixed_dist/*.whl dist/
- name: Upload wheel artifact
# Only upload if it's the "main" CUDA version we want on PyPI
# We upload all to artifacts for inspection/GH releases, but give them distinct artifact names
uses: actions/upload-artifact@v4
with:
name: fastvideo_kernel-py${{ matrix.python-version }}-${{ matrix.torch-cuda.torch-cuda-short }}-torch${{ matrix.torch-cuda.torch-version }}
path: fastvideo-kernel/dist/*.whl
retention-days: 90
publish_package:
name: Publish package
needs: [build_wheels, check-version-change]
if: ${{ needs.check-version-change.outputs.version-changed == 'true' || github.event_name == 'workflow_dispatch' }}
runs-on: ubuntu-22.04
permissions:
id-token: write # Needed for OIDC Trusted Publishing
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Download PyPI wheels
uses: actions/download-artifact@v4
with:
path: fastvideo-kernel/dist/
pattern: 'fastvideo_kernel-py*'
merge-multiple: true
- name: Install uv
uses: astral-sh/setup-uv@v3
- name: Build source distribution
run: |
uv pip install --system build scikit-build-core cmake ninja
cd fastvideo-kernel
# We don't need full CUDA/Torch to just package the source (sdist)
python -m build --sdist --outdir dist
- name: Publish release distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: fastvideo-kernel/dist/
+29 -69
View File
@@ -1,11 +1,17 @@
ucf101_stride4x4x4
__pycache__
*.mp4
.ipynb_checkpoints
*.pth
UCF-101/
results/
build/
fastvideo.egg-info/
wandb/
.idea
*.ipynb
*.jpg
*.mp3
*.safetensors
*.mp4
*.png
@@ -14,81 +20,35 @@ wandb/
*.pt
cache_dir/
wandb/
venv/
.venv/
test*
sample_video*
sample_image*
512*
720*
1024*
debug*
private*
caption*
*deepspeed*
revised*
129f*
all*
read*
YSH*
*pick*
*ysh*
hw*
257f*
513f*
taming*
221hw*
65x512x512
runs/
samples/
Miniconda3-latest-Linux-x86_64.sh
*validation/
data/
outputs/
outputs_video
checkpoints/
sbatch.sh
*.out
env
*.o
**/build/
**.pyc
**.txt
*.log
weights/
logs/
# SSIM test outputs
fastvideo/tests/ssim/generated_videos/
**/.cache/**
# Distribution / packaging
build/
dist/
*.egg-info/
*.egg
eggs/
.eggs/
# MkDocs documentation
site/
docs/getting_started/examples/
docs/inference/examples/
docs/training/examples/
docs/distillation/examples/
!requirements-mkdocs.txt
# VSCode
.vscode/
# DS Store
.DS_Store
# vim swap files
*.swo
*.swp
# Python pickle files
*.pkl
# Reference videos
!fastvideo/tests/ssim/reference_videos/**/*.mp4
# Static images
!docs/assets/images/**/*.png
!comfyui/assets/**/*.png
!comfyui/assets/**/*.gif
!assets/images/**/*.png
!assets/images/**/*.jpg
!assets/images/**/*.jpeg
!assets/images/**/*.gif
!assets/videos/**/*.mp4
dmd_t2v_output/
preprocess_output_text/
# Next.js / Node artifacts under ui/: see ui/.gitignore
.claude/
.codex/
.sisyphus/
openspec/
fastvideo/tests/ssim/reference_videos/**
-6
View File
@@ -1,6 +0,0 @@
[submodule "fastvideo-kernel/include/tk"]
path = fastvideo-kernel/include/tk
url = https://github.com/HazyResearch/ThunderKittens.git
[submodule "fastvideo-kernel/include/cutlass"]
path = fastvideo-kernel/include/cutlass
url = https://github.com/NVIDIA/cutlass.git
-1
View File
@@ -1 +0,0 @@
WRN 2026-03-26T13:46:33.469 ?.19646 server_start:193: Failed to start server: operation not permitted: /var/folders/z_/h_6myyk14d1b7z87z3vy4mjh0000gn/T/nvim.dsynkd/iSe0el/nvim.19646.0
-73
View File
@@ -1,73 +0,0 @@
default_stages:
- pre-commit # Run locally
- manual # Run in CI
exclude: |
(?x)(
fastvideo/third_party/.*|
fastvideo-kernel/.*|
assets/.*|
tests/.*|
scripts/.*|
fastvideo/dataset/.*|
fastvideo/models/.*|
examples/.*|
\.agents/.*|
.github/workflows/publish-fastvideo.yml|
.github/workflows/_template-build-image.yml
)
repos:
- repo: https://github.com/google/yapf
rev: v0.43.0
hooks:
- id: yapf
args: [--in-place, --verbose]
additional_dependencies: [toml] # TODO: Remove when yapf is upgraded
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.11.12
hooks:
- id: ruff
args: [--output-format, github, --fix]
- repo: https://github.com/codespell-project/codespell
rev: v2.4.1
hooks:
- id: codespell
additional_dependencies: ['tomli']
args: ['--toml', 'pyproject.toml']
# - repo: https://github.com/PyCQA/isort
# rev: 6.0.1
# hooks:
# - id: isort
- repo: https://github.com/jackdewinter/pymarkdown
rev: v0.9.30
hooks:
- id: pymarkdown
args: [fix]
- repo: https://github.com/rhysd/actionlint
rev: v1.7.7
hooks:
- id: actionlint
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.15.0
hooks:
- id: mypy
args: [--python-version, '3.10', --follow-imports, "skip", "--disable-error-code", "union-attr", "--disable-error-code", "override" ]
additional_dependencies: [types-aiofiles, types-cachetools, types-setuptools, types-PyYAML, types-requests]
- repo: local
hooks:
- id: check-filenames
name: Check for spaces in all filenames
entry: bash
args:
- -c
- 'git ls-files | grep -v "^\"*fastvideo/tests/ssim/" | grep -v "^\"*fastvideo/tests/inference/lora/L40S_reference_videos/" | grep " " && echo "Filenames should not contain spaces!" && exit 1 || exit 0'
language: system
always_run: true
pass_filenames: false
# Keep `suggestion` last
- id: suggestion
name: Suggestion
entry: bash -c 'echo "To bypass pre-commit hooks, add --no-verify to git commit."'
language: system
verbose: true
pass_filenames: false
# Insert new entries above the `suggestion` entry
-1
View File
@@ -1 +0,0 @@
3.12
-85
View File
@@ -1,85 +0,0 @@
# Repository Guidelines
## Project Structure & Module Organization
- Core Python package: `fastvideo/` (models, pipelines, training, distributed runtime, CLI entrypoints).
- CUDA/custom kernels: `fastvideo-kernel/` (separate build/test flow).
- Tests:
- `fastvideo/tests/` for package-level tests (dataset, encoders, inference, training, SSIM, workflow).
- `tests/local_tests/` for additional local/component checks.
- Docs and guides: `docs/` (MkDocs source), with contributor docs in `docs/contributing/`.
- Runnable examples and scripts: `examples/` and `scripts/`.
- Static assets: `assets/` (including `assets/images/`, `assets/videos/`, and `assets/prompts/`) and `comfyui/assets/`.
## Build, Test, and Development Commands
- `uv pip install -e ".[dev]"`: editable install with lint/test extras.
- `pre-commit install --hook-type pre-commit --hook-type commit-msg`: enable local hooks.
- `pre-commit run --all-files`: run formatter/lint/type/spelling checks.
- `pytest tests/`: run top-level test suite.
- `pytest fastvideo/tests/ -v`: run package tests.
- `pytest fastvideo/tests/ssim/ -vs`: run SSIM regression tests (GPU-heavy).
- `cd fastvideo-kernel && ./build.sh`: build kernel extensions.
## Coding Style & Naming Conventions
- Python 3.10+; 4-space indentation; keep code and imports readable and explicit.
- Style tools are configured in `pyproject.toml` and `.pre-commit-config.yaml`:
- `yapf` (format), `ruff` (lint, auto-fix), `mypy` (typing), `codespell`.
- Lint via `pre-commit run --files <changed paths>` (or `pre-commit run --all-files` for a full sweep) before committing. Do not shell out to `yapf`/`ruff`/`codespell`/`mypy` directly — pre-commit chains them with the project's config and respects the `.pre-commit-config.yaml` excludes (e.g. `fastvideo/tests/` is intentionally skipped). If pre-commit reports `(no files to check)` for your paths, that exclude is deliberate — don't bypass it.
- Target line length is 120 (configured in `pyproject.toml` for ruff, yapf, and isort).
- Naming: `snake_case` for functions/files, `PascalCase` for classes, `UPPER_SNAKE_CASE` for constants.
## Testing Guidelines
- Use `pytest` and place tests near relevant domains (e.g., `fastvideo/tests/encoders/`).
- Prefer descriptive names like `test_<feature>_<expected_behavior>.py`.
- For new pipelines/backends, include at least one regression-oriented test; add SSIM coverage when output quality must be preserved.
- Document GPU assumptions in tests that require specific hardware.
## Commit & Pull Request Guidelines
- Follow existing commit style: short subject with optional tag prefix, e.g. `[bugfix]: ...`, `[feat]: ...`, `[misc]: ...`, and include PR reference like `(#1234)` when applicable.
- Keep commits focused by concern (feature, refactor, fix).
- PRs should include:
- clear problem/solution summary,
- test evidence (`pytest`/SSIM outputs or rationale if skipped),
- linked issue/PR context,
- screenshots or sample outputs for UI/demo/docs changes.
## Agent Infrastructure
This repository is agent-friendly. Before doing any work, read:
1. `.agents/onboarding/README.md` — full onboarding guide with step-by-step instructions.
2. `.agents/memory/codebase-map/README.md` — structural index of the entire repository.
3. `.agents/skills/` — available agent skills (check if one exists before writing code).
4. `.agents/workflows/` — SOPs for common procedures (experiment lifecycle, evaluation, etc.).
5. `.agents/lessons/` — known pitfalls and their documented fixes.
If you are exploring a new procedure that has no existing SOP, document your
progress in `.agents/exploration/` and flag it for review at the end of your
session.
## Per-Directory AGENTS.md
Local guidance lives next to the code. Read the in-scope file before editing:
| Directory | What it covers |
|-----------|----------------|
| `fastvideo/AGENTS.md` | Core package map, public API, registry-driven model dispatch |
| `fastvideo/configs/AGENTS.md` | Arch + pipeline config dataclasses, `param_names_mapping` |
| `fastvideo/models/AGENTS.md` | DiT / VAE / encoder / scheduler / loader layout (pre-commit excluded) |
| `fastvideo/layers/AGENTS.md` | Tensor-parallel linear/attention layer rules for ports |
| `fastvideo/attention/AGENTS.md` | Backend registry + env-var override |
| `fastvideo/pipelines/AGENTS.md` | Stage ABC, `basic/<model>/`, `preprocess/`, presets |
| `fastvideo/training/AGENTS.md` | Legacy monolithic pipelines (frozen for existing models) |
| `fastvideo/train/AGENTS.md` | New modular trainer (methods × models × callbacks, YAML) |
| `fastvideo/tests/AGENTS.md` | Test taxonomy, conftest, pre-commit-excluded path |
| `fastvideo/tests/ssim/AGENTS.md` | GPU SSIM regression authoring + reference video sync |
| `scripts/checkpoint_conversion/AGENTS.md` | Adding a converter for a new HF/official checkpoint |
## Critical: Two Training Stacks Coexist
- `fastvideo/training/` — legacy, monolithic per-model `*_training_pipeline.py` and
`*_distillation_pipeline.py`. Still authoritative for shipped models.
- `fastvideo/train/` — new modular framework (composable methods × models × callbacks
driven by YAML). Preferred for new training work.
Pick the matching stack before editing. Do not migrate a pipeline between them
without an explicit ask — the conventions and config surfaces differ.
-1
View File
@@ -1 +0,0 @@
@AGENTS.md
-182
View File
@@ -1,182 +0,0 @@
# `.agents/` Cleanup Log — Phase 1 (Deletes Only)
**Status:** TEMPORARY — delete this file after the cleanup is reviewed/committed.
**Date:** 2026-05-04
**Branch:** `will/ltx2_sr_port`
**Scope:** Phase 1 of the `.agents/` cleanup plan (deletes only; no rewrites or additions).
For the full multi-phase plan, see the prior session analysis. This file tracks
exactly what got deleted, why, and what cross-references still point at deleted
content (to fix in a future phase).
---
## Deletions executed
### Files deleted
| Path | Size | Reason |
|---|---|---|
| `.agents/STATUS.md` | 3.85 KB | Stale dashboard, last synced 2026-03-02. Counts wrong (claimed 8 skills/4 workflows/4 memory; actual 9/5/5). References old snake_case filenames (`codebase_map.md`/`experiment_journal.md`) that don't exist. Hand-maintained derivative of `.agents/{memory,skills}/index.jsonl` — strictly redundant. |
| `.agents/exploration/pr-link-review.md` | 1.11 KB | Status: "promoted" to `.agents/skills/review-pr-link/`. Per `.agents/exploration/README.md` lifecycle, promoted exploration logs should not linger after the skill exists. |
| `.agents/workflows/sync-dashboard.md` | 1.87 KB | SOP for maintaining `STATUS.md` (which is also deleted). Contained obsolete file paths (`.agents/skills/launch-experiment.md` flat layout vs. actual `<skill>/SKILL.md` per-dir layout). Has never been run successfully (judging by stale dates everywhere). |
### Skill directories deleted
| Path | Size | Reason |
|---|---|---|
| `.agents/skills/index-related-work/` | 2.18 KB | Vapor-skill operating on the empty `.agents/memory/related-work/` registry. Never used (the registry has zero entries despite ~6 weeks since skill creation). Re-add when the related-work catalog gains entries. |
| `.agents/skills/search-related-work/` | 1.91 KB | Same: vapor-skill against empty registry. The skill description literally requires "The related work index has entries" as a prerequisite, and there are none. |
**Total deleted: 5 items, ~10.9 KB.**
### Registry updates
| File | Change |
|---|---|
| `.agents/skills/index.jsonl` | Removed entries for `index-related-work` and `search-related-work`. Was 9 entries; now 7. |
### Symlink hygiene
`.agents/scripts/sync-skills.sh` was run to prune now-stale symlinks under
`.claude/skills/` that pointed at the deleted skill directories. Output captured
in the run log.
---
## What was KEPT (despite being candidates)
| Path | Why kept |
|---|---|
| `.agents/scripts/sync-skills.sh` | User explicitly requested keep. **Verified**: this script is INDEPENDENT of STATUS.md / sync-dashboard.md. It mirrors `.agents/skills/` → `.claude/skills/` via symlinks for Claude Code skill discovery. Self-contained, useful, prunes its own stale symlinks. |
| `.agents/memory/related-work/README.md` | Empty placeholder, but the schema/template is reusable. Kept for when first related-work entry is added. |
| `.agents/memory/experiment-journal/README.md` | Same: empty placeholder with template; kept for when journaling begins. |
| `.agents/lessons/README.md` | Same: empty placeholder, reusable schema. |
| `.agents/exploration/README.md` | Active template for new exploration logs. Kept. |
---
## Remaining broken cross-references (FOLLOW-UP NEEDED)
These files still reference deleted content. **NOT fixed in Phase 1** — track for
the next pass (Phase 2: rewrites/dedupe).
### References to deleted `STATUS.md`
| Referencing file | Action needed |
|---|---|
| `.agents/onboarding/README.md` | Quick-reference tree (line ~65) lists `STATUS.md ← dashboard: completeness & trust of all components`. Remove that line + the `ONBOARDING.md` typo (file is `README.md`). |
### References to deleted `pr-link-review.md`
| Referencing file | Action needed |
|---|---|
| `.agents/memory/dreamverse-integration/state.md` | "Untracked but present" / "Source docs (archived)" sections still mention `pr-link-review.md` as kept. Update to reflect deletion. |
| `.agents/memory/dreamverse-integration/README.md` | Same — table row for `pr-link-review.md` says "kept in exploration dir". Update or remove the row. |
### References to deleted skills (`index-related-work`, `search-related-work`)
| Referencing file | Action needed |
|---|---|
| `.agents/memory/related-work/README.md` | Says "Use the `index-related-work` skill". Either remove that hint or note "skill removed; re-add when registry has entries". |
| `.agents/workflows/evaluation-development.md` | Step 1 says "Search `.agents/memory/related-work/` for existing evaluation approaches" — that's still valid (manual search). No change needed. |
### References to deleted `sync-dashboard.md`
| Referencing file | Action needed |
|---|---|
| `.agents/memory/evaluation-registry/README.md` | Doesn't reference sync-dashboard directly. No change. |
| `.agents/STATUS.md` | Already being deleted. |
---
## Other registry inconsistencies discovered (NOT FIXED in Phase 1)
While editing `.agents/skills/index.jsonl`, two skill directories were found
that exist on disk but **are not registered** in `index.jsonl`:
| Skill dir | Status | Why missing from index |
|---|---|---|
| `.agents/skills/diagnose-ssim-failure/` | Untracked locally; NOT on `origin/main`. 12.3 KB SKILL.md + `scripts/compare_latent_pt.py`. Recent mtime (2026-05-01). | Created in a prior session but the registration step was skipped. |
| `.agents/skills/review-pr-link/` | Untracked locally; NOT on `origin/main`. 2.9 KB SKILL.md + `scripts/prepare_pr_review.py` + `agents/openai.yaml`. The promotion target of the deleted `pr-link-review.md` exploration log. | Skipped registration when promoted from exploration log. |
Both skills are functional and exposed via `sync-skills.sh` symlinks (just verified in
`.claude/skills/`), but agents reading `index.jsonl` to discover skills will miss them.
**Action for Phase 2**: Add entries to `.agents/skills/index.jsonl` for both,
likely with `trust: medium` since they have working scripts and recent use.
---
## Skill registry parity check
After Phase 1, `.agents/skills/` contains 9 directories but `index.jsonl` lists 7:
| In `index.jsonl` | On disk |
|---|---|
| ✓ launch-experiment | ✓ launch-experiment/ |
| ✓ monitor-experiment | ✓ monitor-experiment/ |
| ✓ summarize-run | ✓ summarize-run/ |
| ✓ log-experiment | ✓ log-experiment/ |
| ✓ evaluate-video-quality | ✓ evaluate-video-quality/ |
| ✓ seed-ssim-references | ✓ seed-ssim-references/ |
| ✓ reseed-ssim-references | ✓ reseed-ssim-references/ |
| ❌ (missing) | ⚠ diagnose-ssim-failure/ |
| ❌ (missing) | ⚠ review-pr-link/ |
`.claude/skills/` symlinks (the runtime-discoverable surface) include all 9 ✓.
---
## Phase 2+ items (NOT executed in this session)
For future cleanup sessions, the prior plan identified:
**Phase 2 (rewrites)**:
- Rewrite `.agents/onboarding/worldmodel-training/README.md` to drop ~50% structural duplication with `codebase-map/README.md`
- Refresh `.agents/memory/codebase-map/README.md` (last updated 2026-03-08; missing `fastvideo/api/`, `fastvideo/entrypoints/streaming/`, etc.)
- Refresh `.agents/memory/evaluation-registry/README.md` (last updated 2026-03-02; references old `evaluation_registry.md` filename)
- Merge `.agents/workflows/experiment-journaling.md` into `experiment-lifecycle.md` (one SOP per workflow)
- Fix the broken cross-references listed above
**Phase 3 (additions)**:
- `fastvideo/api/AGENTS.md`
- `fastvideo/entrypoints/AGENTS.md`
- `tests/AGENTS.md` (top-level, distinct from `fastvideo/tests/AGENTS.md`)
- `fastvideo/distributed/AGENTS.md`
- `examples/AGENTS.md`
- `docs/AGENTS.md`
- `benchmarks/AGENTS.md`
**Phase 4 (registry)**:
- Add `.agents/workflows/index.jsonl`
- Standardize all three index.jsonl schemas
**Phase 5 (skills quality)**:
- Promote tested skills (`seed-ssim-references`, `reseed-ssim-references`, `diagnose-ssim-failure`, `review-pr-link`) from `trust: low` to `trust: medium`
- Mark untested skills (`launch-experiment`, `monitor-experiment`, `summarize-run`, `log-experiment`, `evaluate-video-quality`) explicitly with their gating prerequisite (e.g. "operates on empty registry")
---
## Recovery
All deletions are local (`will/ltx2_sr_port`, not committed). To restore any
deleted file:
```bash
git restore --source=HEAD .agents/STATUS.md
git restore --source=HEAD .agents/exploration/pr-link-review.md
git restore --source=HEAD .agents/workflows/sync-dashboard.md
git restore --source=HEAD .agents/skills/index-related-work/SKILL.md
git restore --source=HEAD .agents/skills/search-related-work/SKILL.md
```
---
## When to delete THIS file
Once:
1. The Phase 1 deletions are committed (or merged), AND
2. Phase 2 (broken cross-reference cleanup) is also committed,
remove this file. Its purpose is transient bookkeeping for a multi-phase cleanup.
-88
View File
@@ -1,88 +0,0 @@
# Co-Authors — `will/ltx2_sr_port` Stack
**Status:** PERMANENT — keep around as the source of truth for who collaborated on this work, even after the stack merges.
**Last updated:** 2026-05-04
This file documents the human co-authors credited on every commit in the
`will/ltx2_sr_port` stack and its 10 split PRs. The 4 collaborators below
worked on the FastVideo-internal precursor of this code (LTX-2 streaming
server, NVFP4 wire-up, GPU pool, prompt enhancer, etc.) and are credited as
co-authors on the public-side upstream commits via Git's standard
[`Co-authored-by`](https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors)
trailer convention.
The trailers are added to every commit on `will/ltx2_sr_port` (see
[`STACK.md`](STACK.md)), which means GitHub will:
- Show the 4 co-authors on every commit detail page
- Show them on the merge commit / squash commit summary
- Display their avatars in the PR's "Contributors" sidebar
- Surface them in [`/contributors`](https://github.com/hao-ai-lab/FastVideo/contributors) once the stack lands
## Co-author roster
| GitHub user | Real name | GitHub ID | Trailer email |
|---|---|---|---|
| [`@Davids048`](https://github.com/Davids048) | Junda (David) Su | 90978028 | `90978028+Davids048@users.noreply.github.com` |
| [`@RandNMR73`](https://github.com/RandNMR73) | Matthew Noto | 99706358 | `99706358+RandNMR73@users.noreply.github.com` |
| [`@XOR-op`](https://github.com/XOR-op) | (unset) | 17672363 | `17672363+XOR-op@users.noreply.github.com` |
| [`@jzhang38`](https://github.com/jzhang38) | Zhang Peiyuan | 42993249 | `42993249+jzhang38@users.noreply.github.com` |
## Why no-reply emails
GitHub's `<id>+<username>@users.noreply.github.com` form is the most reliable
way to link a `Co-authored-by` trailer to a GitHub account. It:
- Always works regardless of whether the user has a public verified email
- Survives the user changing their primary email
- Doesn't expose anyone's personal email to git history
- Is the format GitHub itself produces when you click "Add co-author" in the
web UI
(All 4 collaborators have this email already used in `FastVideo-internal`
git history, verified via `git log --all` on that repo.)
## Trailer block (copy-paste ready)
The trailers added to every commit on `will/ltx2_sr_port`:
```
Co-authored-by: Junda (David) Su <90978028+Davids048@users.noreply.github.com>
Co-authored-by: Matthew Noto <99706358+RandNMR73@users.noreply.github.com>
Co-authored-by: XOR-op <17672363+XOR-op@users.noreply.github.com>
Co-authored-by: Zhang Peiyuan <42993249+jzhang38@users.noreply.github.com>
```
## How the trailers were applied
```bash
git rebase --exec '
git commit --amend --no-edit \
--trailer "Co-authored-by: Junda (David) Su <90978028+Davids048@users.noreply.github.com>" \
--trailer "Co-authored-by: Matthew Noto <99706358+RandNMR73@users.noreply.github.com>" \
--trailer "Co-authored-by: XOR-op <17672363+XOR-op@users.noreply.github.com>" \
--trailer "Co-authored-by: Zhang Peiyuan <42993249+jzhang38@users.noreply.github.com>"
' origin/main will/ltx2_sr_port
```
Git's `--trailer` flag is idempotent (it dedupes by the full `key: value`
string), so re-running the rebase is safe and won't add duplicates.
## How to add a new co-author later
1. Add the user to the roster table above.
2. Append their `Co-authored-by` line to the trailer block.
3. Re-run the rebase command above on `will/ltx2_sr_port` — git's
trailer dedupe handles the existing 4; the new one gets appended.
4. Re-slice all 10 split branches per [`STACK.md`](STACK.md).
5. Force-push `will/api_7.6`, `will/api_7.7`, and `will/ltx2_sr_port`.
## What we do NOT add
Per [`AGENTS.md`](AGENTS.md):
> Never add any coding agent or models such as Claude (or Claude Code), GPT,
> Codex or others as a co-author in commits or PRs.
So no `Co-authored-by: Claude <noreply@anthropic.com>` or similar. Only
human collaborators.
+17 -183
View File
@@ -1,187 +1,21 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
MIT License
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Copyright (c) 2024 PKU-YUAN's Group (袁粒课题组-北大信工) and Rabbitpre AI
1. Definitions.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+88 -137
View File
@@ -1,157 +1,108 @@
<div align="center">
<img src=assets/logos/logo.svg width="30%"/>
</div>
# Fast Video
This is currently based on Open-Sora-1.2.0: https://github.com/PKU-YuanGroup/Open-Sora-Plan/tree/294993ca78bf65dec1c3b6fb25541432c545eda9
<p align="center">
| <a href="https://hao-ai-lab.github.io/FastVideo"><b>Documentation</b></a> | <a href="https://hao-ai-lab.github.io/FastVideo/inference/inference_quick_start/"><b> Quick Start</b></a> | <a href="https://github.com/hao-ai-lab/FastVideo/discussions/982" target="_blank"><b>Weekly Dev Meeting</b></a> | 🟣💬 <a href="https://join.slack.com/t/fastvideo/shared_invite/zt-3f4lao1uq-u~Ipx6Lt4J27AlD2y~IdLQ" target="_blank"> <b>Slack</b> </a> | 🟣💬 <a href="https://github.com/hao-ai-lab/FastVideo/discussions/1097" target="_blank"> <b> WeChat </b> </a> |
</p>
**FastVideo is a unified post-training and real-time inference framework for accelerated video generation.**
## NEWS
- `2026/03/17`: Release Live demo: [Into the Dreamverse: Vibe Directing in FastVideo](https://dreamverse.fastvideo.org/), check out the [Blog](https://haoailab.com/blogs/dreamverse/).
- `2026/03/13`: Release Live demo: [Create a 5s 1080p Video in 4.5s with FastVideo on a Single GPU](https://1080p.fastvideo.org/), check out the [Blog](https://haoailab.com/blogs/fastvideo_realtime_1080p/).
- `2025/11/19`: Release [CausalWan2.2 I2V A14B Preview](https://huggingface.co/FastVideo/CausalWan2.2-I2V-A14B-Preview-Diffusers) models, [Blog](https://hao-ai-lab.github.io/blogs/fastvideo_causalwan_preview/) and [Inference Code!](https://github.com/hao-ai-lab/FastVideo/blob/main/examples/inference/basic/basic_self_forcing_causal_wan2_2_i2v.py).
- `2025/08/04`: Release [FastWan](https://hao-ai-lab.github.io/FastVideo/distillation/dmd) models and [Sparse-Distillation](https://hao-ai-lab.github.io/blogs/fastvideo_post_training/).
### More News
- `2025/06/14`: Release finetuning and inference code for [VSA](https://arxiv.org/pdf/2505.13389).
- `2025/04/24`: [FastVideo V1](https://hao-ai-lab.github.io/blogs/fastvideo/) is released!
- `2025/02/18`: Release the inference code for [Sliding Tile Attention](https://hao-ai-lab.github.io/blogs/sta/).
## Key Features
FastVideo has the following features:
- End-to-end post-training support for bidirectional and autoregressive models:
- Support full finetuning and LoRA finetuning for state-of-the-art open video DiTs
- Data preprocessing pipeline for video, image, and text data
- Distribution Matching Distillation (DMD2) stepwise distillation.
- Sparse attention with [Video Sparse Attention](https://arxiv.org/pdf/2505.13389)
- [Sparse distillation](https://hao-ai-lab.github.io/blogs/fastvideo_post_training/) to achieve >50x denoising speedup
- Scalable training with FSDP2, sequence parallelism, and selective activation checkpointing.
- Causal distillation through Self-Forcing
- See this [page](https://hao-ai-lab.github.io/FastVideo/training/overview/) for full list of supported models and recipes.
- State-of-the-art performance optimizations for inference
- Sequence Parallelism for distributed inference
- Multiple state-of-the-art attention backends
- User-friendly CLI and Python API
- See this [page](https://hao-ai-lab.github.io/FastVideo/inference/optimizations/) for full list of supported optimizations.
- Diverse hardware and OS support
- Support H100, A100, 4090
- Support Linux, Windows, MacOS
- See this [page](https://hao-ai-lab.github.io/FastVideo/inference/support_matrix/) for full list of supported models, hardware assumptions, and optimization compatibility.
## Getting Started
We recommend using [uv](https://docs.astral.sh/uv/) to create a clean environment. If you previously used Conda, switching to uv generally gives faster and more stable installs.
```bash
# Create and activate a new uv environment
uv venv --python 3.12 --seed
source .venv/bin/activate
# Install FastVideo
uv pip install fastvideo
## Envrironment
Change the index-url cuda version according to your system.
```
conda create -n fastvideo python=3.10.12
conda activate fastvideo
pip3 install torch==2.5.0 torchvision --index-url https://download.pytorch.org/whl/cu121
pip install git+https://github.com/huggingface/diffusers.git@76b7d86a9a5c0c2186efa09c4a67b5f5666ac9e3
pip install packaging ninja && pip install flash-attn==2.7.0.post2 --no-build-isolation
```
Please see our [docs](https://hao-ai-lab.github.io/FastVideo/getting_started/installation/) for more detailed installation instructions.
## Sparse Distillation
For our sparse distillation techniques, please see our [distillation docs](https://hao-ai-lab.github.io/FastVideo/distillation/dmd/) and check out our [blog](https://hao-ai-lab.github.io/blogs/fastvideo_post_training/).
See below for recipes and datasets:
| Model | Sparse Distillation | Dataset |
| ------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| [FastWan2.1-T2V-1.3B](https://huggingface.co/FastVideo/FastWan2.1-T2V-1.3B-Diffusers) | [Recipe](https://github.com/hao-ai-lab/FastVideo/tree/main/examples/distill/Wan2.1-T2V/Wan-Syn-Data-480P) | [FastVideo Synthetic Wan2.1 480P](https://huggingface.co/datasets/FastVideo/Wan-Syn_77x448x832_600k) |
| [FastWan2.2-TI2V-5B](https://huggingface.co/FastVideo/FastWan2.2-TI2V-5B-Diffusers) | [Recipe](https://github.com/hao-ai-lab/FastVideo/tree/main/examples/distill/Wan2.2-TI2V-5B-Diffusers/Data-free) | [FastVideo Synthetic Wan2.2 720P](https://huggingface.co/datasets/FastVideo/Wan2.2-Syn-121x704x1280_32k) |
## Inference
### Generating Your First Video
Here's a minimal example to generate a video using the default settings. Make sure VSA kernels are [installed](https://hao-ai-lab.github.io/FastVideo/attention/vsa/#installation). Create a file called `example.py` with the following code:
```python
import os
from fastvideo import VideoGenerator
def main():
os.environ["FASTVIDEO_ATTENTION_BACKEND"] = "VIDEO_SPARSE_ATTN"
# Create a video generator with a pre-trained model
generator = VideoGenerator.from_pretrained(
"FastVideo/FastWan2.1-T2V-1.3B-Diffusers",
num_gpus=1, # Adjust based on your hardware
)
# Define a prompt for your video
prompt = "A curious raccoon peers through a vibrant field of yellow sunflowers, its eyes wide with interest."
# Generate the video
video = generator.generate_video(
prompt,
output_path="my_videos/", # Controls where videos are saved
save_video=True
)
if __name__ == '__main__':
main()
```
pip install -e . && pip install -e ".[train]"
sudo apt-get update && apt install screen && pip install watch gpustat
```
Run the script with:
## Prepare Data & Models
We've prepared some debug data to facilitate development. To make sure the training pipeline is correct, train on the debug data and make sure the model overfit on it (feed it the same text prompt and see if the output video is the same as the training data)
```bash
python example.py
```
mkdir data && mkdir data/outputs/
python scripts/download_hf.py --repo_id=Stealths-Video/mochi_diffuser --local_dir=data/mochi --repo_type=model
python scripts/download_hf.py --repo_id=Stealths-Video/Merge-30k-Data --local_dir=data/Merge-30k-Data --repo_type=dataset
python scripts/download_hf.py --repo_id=Stealths-Video/validation_embeddings --local_dir=data/validation_embeddings --repo_type=dataset
cd data/Merge-30k-Data
cat Merged30K.tar.gz.part.* > Merged30K.tar.gz
rm Merged30K.tar.gz.part.*
tar --use-compress-program="pigz --processes 64" -xvf Merged30K.tar.gz
mv ephemeral/hao.zhang/codefolder/FastVideo-OSP/data/Merged-30K-Data/* .
rm -r ephemeral
rm Merged30K.tar.gz
cd ../..
```
For a more detailed guide, please see our [inference quick start](https://hao-ai-lab.github.io/FastVideo/inference/inference_quick_start/).
## Things Learned
1. shift8 clear but got structural artifacts
2. lq, 0.025 vague
3. adv not really helpful
4. shift8 euler steps 50 v.s. 100 very similar
5. 为啥image不会越distill越炸
6. EMA, 大batchsize, 1.5,2.5,3.5,4.5
7. Must have schedule
8. phase 1, 2 learning rate 5e-6不行
## More Guides
## Experiments
Scripts are located at scripts/experiment_N.sh
- [Design Overview](https://hao-ai-lab.github.io/FastVideo/design/overview/)
- [Distillation Guide](https://hao-ai-lab.github.io/FastVideo/distillation/dmd/)
- [Contribution Guide](https://hao-ai-lab.github.io/FastVideo/contributing/overview/)
1. pcm_linear_quadratic, euler_steps 50, 0.025
2. pcm_linear_quadratic, euler_steps 50, 0.05
3. shift 8, euler_steps 100
4. shift 8, euler_steps 50
5. shift 8, euler_steps 100, adv
6. pcm_linear_quadratic, euler_steps 50, 0.025, adv
7. pcm_linear_quadratic, euler_steps 50, 0.05, multiphase 125
8. pcm_linear_quadratic, euler_steps 50, 0.1, linear_range 0.75
9. pcm_linear_quadratic, euler_steps 50, 0.05, range 0.75
10. pcm_linear_quadratic, euler_steps 50, 0.05, batchsize 32
11. pcm_linear_quadratic, euler_steps 50, learning rate,1e-7
12. shift1, euler_steps 50
## Awesome work using FastVideo or our research projects
13. pcm_linear_quadratic, euler_steps 50, 0.1, linear_range 0.75, phase 1
14. 4.5 cfg, validation no cfg, pcm_linear_quadratic, euler_steps 50, 0.1, linear_range 0.75
15. pcm_linear_quadratic, euler_steps 50, 0.15, linear_range 0.75
16. pcm_linear_quadratic, euler_steps 50, 0.1, linear_range 0.75 ema 0.95, decay 0.0
- [SGLang](https://github.com/sgl-project/sglang/tree/main/python/sglang/multimodal_gen): SGLang's diffusion inference functionality is based on a fork of FastVideo on Sept. 24, 2025.
- [DanceGRPO](https://github.com/XueZeyue/DanceGRPO): A unified framework to adapt Group Relative Policy Optimization (GRPO) to visual generation paradigms. Code based on FastVideo.
- [SRPO](https://github.com/Tencent-Hunyuan/SRPO): A method to directly align the full diffusion trajectory with fine-grained human preference. Code based on FastVideo.
- [DCM](https://github.com/Vchitect/DCM): Dual-expert consistency model for efficient and high-quality video generation. Code based on FastVideo.
- [HY-WorldPlay](https://github.com/Tencent-Hunyuan/HY-WorldPlay): An action-conditioned world model model trained using FastVideo framework.
- [Hunyuan Video 1.5](https://github.com/Tencent-Hunyuan/HunyuanVideo-1.5): A leading lightweight video generation model, where they proposed SSTA based on Sliding Tile Attention.
- [Kandinsky-5.0](https://github.com/kandinskylab/kandinsky-5): A family of diffusion models for video & image generation, where their NABLA attention includes a Sliding Tile Attention branch.
- [LongCat Video](https://github.com/meituan-longcat/LongCat-Video): A foundational video generation model with 13.6B parameters with block-sparse attention similar to Video Sparse Attention.
## 🤝 Contributing
17. no cfg, validation no cfg, pcm_linear_quadratic, euler_steps 50, 0.1, linear_range 0.75
18. shift16, euler_steps 50
We welcome all contributions. Please check out our guide [here](https://hao-ai-lab.github.io/FastVideo/contributing/overview/).
See details in [development roadmap](https://github.com/hao-ai-lab/FastVideo/issues/899).
19. 4step_infer_shift16_euler_50
20. 4step_infer_shift12_euler_50
21. 4step_infer_lq_euler_50_thresh0.1_lrg_0.75
22. pcm_linear_quadratic, euler_steps 50, 0.1, linear_range 0.75, phase 1, lr 1e-7
23. lq_euler_50_thres0.1_lrg_0.75_bs_64
24. lq_euler_50_thres0.1_lrg_0.75_lr5e-7
## Acknowledgement
We learned the design and reused code from the following projects: [Wan-Video](https://github.com/Wan-Video), [ThunderKittens](https://github.com/HazyResearch/ThunderKittens), [DMD2](https://github.com/tianweiy/DMD2), [diffusers](https://github.com/huggingface/diffusers), [xDiT](https://github.com/xdit-project/xDiT), [vLLM](https://github.com/vllm-project/vllm), [SGLang](https://github.com/sgl-project/sglang). We thank [MBZUAI](https://ifm.mbzuai.ac.ae/), [Anyscale](https://www.anyscale.com/), and [GMI Cloud](https://www.gmicloud.ai/) for their support throughout this project.
## Citation
25. shift1_euler_50_0.75_phase1
26. kill
27. pcm_linear_quadratic, euler_steps 50, 0.1, linear_range 0.75, phase 1, ema 0.95, cfg 4.5
If you find FastVideo useful, please consider citing our research work:
28. lq_euler_50_thresh0.1_lrg_0.75_phase1_ema0.95
29. lq_euler_50_thres0.1_lrg_0.75_phase_ema0.95_cfg7
30. lq_euler_50_thresh0.1_lrg_0.75_phase1_ema0.98_cfg4.5
31. lq_euler_50_thresh0.1_lrg_0.75_phase1_lr_3e-7
32. lq_euler_50_thresh0.15_lrg_0.75_phase1_ema0.95_cfg4.5
33. lq_euler_50_thres0.1_linear_range_0.75_repro
34. lq_euler_50_thres0.1_lrg_0.75_reproduc
```bibtex
@article{zhang2025vsa,
title={Vsa: Faster video diffusion with trainable sparse attention},
author={Zhang, Peiyuan and Chen, Yongqi and Huang, Haofeng and Lin, Will and Liu, Zhengzhong and Stoica, Ion and Xing, Eric and Zhang, Hao},
journal={arXiv preprint arXiv:2505.13389},
year={2025}
}
35. pcm_linear_quadratic, euler_steps 50, 0.1, linear_range 0.75, phase 1, learning rate 5e-6
36. pcm_linear_quadratic, euler_steps 50, 0.1, linear_range 0.75, phase 2, learning rate 1e-6
37. pcm_linear_quadratic, euler_steps 50, 0.1, linear_range 0.75, phase 2, learning rate 5e-6
38. lq_euler_50_thres0.1_linear_range_0.75, learning rate 5e-6
39. lq_euler_50_thres0.1_linear_range_0.75, learning rate 1e-5
40. lq_euler_50_thres0.1_lrg_0.75_phase1_lr1e-6_repro
@article{zhang2025fast,
title={Fast video generation with sliding tile attention},
author={Zhang, Peiyuan and Chen, Yongqi and Su, Runlong and Ding, Hangliang and Stoica, Ion and Liu, Zhengzhong and Zhang, Hao},
journal={arXiv preprint arXiv:2502.04507},
year={2025}
}
```
41. lq_euler_50_thres0.1_lrg_0.75_reproduce
42. pcm_linear_quadratic, euler_steps 50, 0.1, linear_range 0.75, phase 4, learning rate 1e-6
43. pcm_linear_quadratic, euler_steps 50, 0.1, linear_range 0.75, phase 1, learning rate 1e-6, cfg 6.0
44. lq_euler_50_thres0.1_lrg_0.75_phase1_lr_5e-6_test_norm
45. lq_euler_50_thres0.1_lrg_0.75_phase1_lr_5e-6_pred_decay_0.1_latent14
46-48. lq_euler_50_thres0.1_lrg_0.75_phase1_lr1e-6, l2 or l1, decay weight 0.1 to 0.001
49.
-10
View File
@@ -1,10 +0,0 @@
try:
from .comfyui.video_generator.nodes import (NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS)
WEB_DIRECTORY = "./web"
__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS', 'WEB_DIRECTORY']
except ImportError:
# ComfyUI environment not available, skip comfyui imports
NODE_CLASS_MAPPINGS = {}
NODE_DISPLAY_NAME_MAPPINGS = {}
WEB_DIRECTORY = "./web"
__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS', 'WEB_DIRECTORY']
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 MiB

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 194 KiB

-18
View File
@@ -1,18 +0,0 @@
<svg width="252" height="105" viewBox="0 0 252 105" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M89.4843 55.5457H101.361L87.7028 101H74.638L89.4843 55.5457Z" fill="#356CFF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M96.0167 1.00057H112.645L118.583 48.273H104.924L103.737 39.7882H79.9827L67.5117 55.5457H85.3273L43.1638 101H28.3174L22.3789 55.5457H33.6621L38.4129 91.3031L58.604 68.2729H44.3515L96.0167 1.00057ZM100.768 13.1217L87.7028 29.4852H103.143L100.768 13.1217Z" fill="#356CFF"/>
<path d="M37.2252 1.00057L22.3789 48.273H36.0375L40.7884 30.6974L62.6727 30.6974L69.6727 21.0005L43.7576 21.0004L46.7269 11.9096L77.6727 11.9096L86 1.00057L37.2252 1.00057Z" fill="#356CFF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M108.488 55.5457L94.2351 101C94.2351 101 105.518 101 120.959 101C136.399 101 144.078 93.0133 148.276 79.788C152.432 68.0157 153.027 55.5457 136.399 55.5457C119.771 55.5457 108.488 55.5457 108.488 55.5457ZM109.081 90.697L116.802 65.8487C116.802 65.8487 120.959 65.8487 132.242 65.8487C143.525 65.8487 137.586 78.5759 135.211 84.0304C133.307 88.4021 127.491 90.697 122.74 90.697C117.989 90.697 109.081 90.697 109.081 90.697Z" fill="#356CFF"/>
<path d="M173.188 1.00056L168.625 11.9096C168.625 11.9096 149.386 11.9092 142.525 11.9095C135.664 11.9098 136.586 20.3944 141.337 20.3944H159.747C168.654 20.3944 166.961 33.6899 163.904 38.5761C160.467 44.0675 157.371 48.273 148.463 48.273L125.188 48.273L124 37.97L147.87 37.97C153.808 37.97 156.184 29.4852 151.433 29.4852H131.836C120.142 29.4852 125.897 1.00043 141.337 1.00043L173.188 1.00056Z" fill="#356CFF"/>
<path d="M179.938 1.00056L175.688 11.9096L191.221 11.9096L179.938 48.273H192.409L203.692 11.9096L219.132 11.9095L223.289 1.00043L179.938 1.00056Z" fill="#356CFF"/>
<path d="M161.341 55.5457H202.845L198.5 65.8487H169.654L167.279 73.7268H188.5L184.749 82.8177H164.31L161.934 90.697H190.251L186.624 101H146.494L161.341 55.5457Z" fill="#356CFF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M230.821 54.9391C255.169 54.9391 251.776 67.0602 249.231 77.9692C246.686 88.8783 240.917 101 217.757 101C194.596 101 195.606 88.8783 199.347 77.9692C203.089 67.0602 206.473 54.9391 230.821 54.9391ZM237.948 77.9692C239.984 70.6965 240.917 65.242 228.446 65.242C215.975 65.242 211.818 71.9087 210.037 77.9692C208.255 84.0298 208.255 91.3025 219.538 91.3025C230.821 91.3025 235.911 85.2419 237.948 77.9692Z" fill="#356CFF"/>
<path d="M173.188 1.00056L168.625 11.9096C168.625 11.9096 149.386 11.9092 142.525 11.9095C135.664 11.9098 136.586 20.3944 141.337 20.3944M173.188 1.00056C173.188 1.00056 156.777 1.00043 141.337 1.00043M173.188 1.00056L141.337 1.00043M141.337 20.3944C146.088 20.3944 150.839 20.3944 159.747 20.3944M141.337 20.3944H159.747M159.747 20.3944C168.654 20.3944 166.961 33.6899 163.904 38.5761C160.467 44.0675 157.371 48.273 148.463 48.273M148.463 48.273C139.556 48.273 125.188 48.273 125.188 48.273M148.463 48.273L125.188 48.273M125.188 48.273L124 37.97M124 37.97C124 37.97 141.931 37.97 147.87 37.97M124 37.97L147.87 37.97M147.87 37.97C153.808 37.97 156.184 29.4852 151.433 29.4852M151.433 29.4852C146.682 29.4852 138.962 29.4852 131.836 29.4852M151.433 29.4852H131.836M131.836 29.4852C120.142 29.4852 125.897 1.00043 141.337 1.00043M37.2252 1.00057L22.3789 48.273H36.0375L40.7884 30.6974L62.6727 30.6974L69.6727 21.0005L43.7576 21.0004L46.7269 11.9096L77.6727 11.9096L86 1.00057L37.2252 1.00057ZM96.0167 1.00057H112.645L118.583 48.273H104.924L103.737 39.7882H79.9827L67.5117 55.5457H85.3273L43.1638 101H28.3174L22.3789 55.5457H33.6621L38.4129 91.3031L58.604 68.2729H44.3515L96.0167 1.00057ZM87.7028 29.4852L100.768 13.1217L103.143 29.4852H87.7028ZM89.4843 55.5457H101.361L87.7028 101H74.638L89.4843 55.5457ZM108.488 55.5457L94.2351 101C94.2351 101 105.518 101 120.959 101C136.399 101 144.078 93.0133 148.276 79.788C152.432 68.0157 153.027 55.5457 136.399 55.5457C119.771 55.5457 108.488 55.5457 108.488 55.5457ZM116.802 65.8487L109.081 90.697C109.081 90.697 117.989 90.697 122.74 90.697C127.491 90.697 133.307 88.4021 135.211 84.0304C137.586 78.5759 143.525 65.8487 132.242 65.8487C120.959 65.8487 116.802 65.8487 116.802 65.8487ZM179.938 1.00056L175.688 11.9096L191.221 11.9096L179.938 48.273H192.409L203.692 11.9096L219.132 11.9095L223.289 1.00043L179.938 1.00056ZM161.341 55.5457H202.845L198.5 65.8487H169.654L167.279 73.7268H188.5L184.749 82.8177H164.31L161.934 90.697H190.251L186.624 101H146.494L161.341 55.5457ZM230.821 54.9391C255.169 54.9391 251.776 67.0602 249.231 77.9692C246.686 88.8783 240.917 101 217.757 101C194.596 101 195.606 88.8783 199.347 77.9692C203.089 67.0602 206.473 54.9391 230.821 54.9391ZM228.446 65.242C240.917 65.242 239.984 70.6965 237.948 77.9692C235.911 85.2419 230.821 91.3025 219.538 91.3025C208.255 91.3025 208.255 84.0298 210.037 77.9692C211.818 71.9087 215.975 65.242 228.446 65.242Z" stroke="#356CFF" stroke-width="1.18771"/>
<path d="M15.2524 55.5451L21.191 100.999L24.7541 100.999L18.8156 55.5451L15.2524 55.5451Z" fill="#356CFF" stroke="#356CFF" stroke-width="1.18771"/>
<path d="M8.12646 55.5451L14.065 100.999L15.2527 100.999L9.31417 55.5451L8.12646 55.5451Z" fill="#356CFF" stroke="#356CFF" stroke-width="1.18771"/>
<path d="M1 55.5451L6.93853 100.999L7.53239 100.999L1.59385 55.5451L1 55.5451Z" fill="#356CFF" stroke="#356CFF" stroke-width="0.593853"/>
<path d="M15.2524 48.2724L30.0988 1H33.6619L18.8156 48.2724H15.2524Z" fill="#356CFF" stroke="#356CFF" stroke-width="1.18771"/>
<path d="M8.12646 48.2724L22.9728 1H24.1605L9.31417 48.2724H8.12646Z" fill="#356CFF" stroke="#356CFF" stroke-width="1.18771"/>
<path d="M1 48.2724L15.8463 1H16.4402L1.59385 48.2724H1Z" fill="#356CFF" stroke="#356CFF" stroke-width="0.593853"/>
<path d="M85.3271 55.5457H67.5116L87 12.7363L44.3513 68.2729H58.6038L43.1636 101L85.3271 55.5457Z" fill="#FDC717" stroke="#FDC717" stroke-width="1.18771" stroke-miterlimit="16"/>
</svg>

Before

Width:  |  Height:  |  Size: 5.7 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 490 KiB

-6
View File
@@ -1,6 +0,0 @@
<svg width="160" height="93" viewBox="0 0 160 93" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M28.8511 91.66L57.6319 1.86368H64.5394L35.7585 91.66H28.8511Z" fill="#356CFF" stroke="#356CFF" stroke-width="2.30244"/>
<path d="M15.0376 91.66L43.8185 1.86368H46.1209L17.3401 91.66H15.0376Z" fill="#356CFF" stroke="#356CFF" stroke-width="2.30244"/>
<path d="M1.22217 91.66L30.003 1.86366H31.1543L2.3734 91.66H1.22217Z" fill="#356CFF" stroke="#356CFF" stroke-width="1.15122"/>
<path d="M71.4465 1.86483L42.666 91.6599H69.144L78.3538 58.2746H123.251L129.007 39.855H84.1099L89.866 22.5868H152.032L157.788 1.86483H71.4465Z" fill="#356CFF" stroke="#356CFF" stroke-width="2.30244"/>
</svg>

Before

Width:  |  Height:  |  Size: 691 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 229 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 723 KiB

Some files were not shown because too many files have changed in this diff Show More