{"id":7404,"date":"2026-09-30T01:19:30","date_gmt":"2026-09-29T16:19:30","guid":{"rendered":"https:\/\/localmodelwatch.tsuchitsuchi.com\/2026\/09\/30\/longlive-plug-wan2-1-t2v-14b-cfg\/"},"modified":"2026-10-02T13:33:49","modified_gmt":"2026-10-02T04:33:49","slug":"longlive-plug-wan2-1-t2v-14b-cfg","status":"publish","type":"post","link":"https:\/\/localmodelwatch.tsuchitsuchi.com\/en\/2026\/09\/30\/longlive-plug-wan2-1-t2v-14b-cfg\/","title":{"rendered":"LongLive-Plug-Wan2.1-T2V-14B-cfg: Our Generated Video, File List"},"content":{"rendered":"<p><!-- lmw:facts --><\/p>\n<h2>At a Glance<\/h2>\n<div class=\"lmw-table-scroll\" tabindex=\"0\" style=\"overflow-x:auto;-webkit-overflow-scrolling:touch;max-width:100%;\">\n<table style=\"width:max-content;min-width:100%;border-collapse:collapse;\">\n<thead>\n<tr>\n<th>Item<\/th>\n<th>Value<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Repository<\/td>\n<td><a href=\"https:\/\/huggingface.co\/Efficient-Large-Model\/LongLive-Plug-Wan2.1-T2V-14B-cfg\">Efficient-Large-Model\/LongLive-Plug-Wan2.1-T2V-14B-cfg<\/a><\/td>\n<\/tr>\n<tr>\n<td>Publisher guide<\/td>\n<td><a href=\"https:\/\/localmodelwatch.tsuchitsuchi.com\/en\/publisher-efficient-large-model-en\/\">Efficient Large Model (NVIDIA and MIT): models and licenses<\/a><\/td>\n<\/tr>\n<tr>\n<td>Published<\/td>\n<td>2026-09-29<\/td>\n<\/tr>\n<tr>\n<td>License<\/td>\n<td>apache-2.0<\/td>\n<\/tr>\n<tr>\n<td>Formats<\/td>\n<td><a href=\"https:\/\/localmodelwatch.tsuchitsuchi.com\/en\/format-safetensors-en\/\">safetensors<\/a><\/td>\n<\/tr>\n<tr>\n<td>Source type<\/td>\n<td>Primary source (the publisher itself)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p><em>Values determined by this site&#8217;s code when the information was collected. Dates are JST.<\/em><\/p>\n<p><!-- \/lmw:facts --><\/p>\n<p><!-- lmw:lab-summary --><\/p>\n<p><strong>What we checked ourselves<\/strong><\/p>\n<ul>\n<li>We generated video on a rented cloud GPU from our own fixed prompts and show it unedited.<\/li>\n<\/ul>\n<p>Details and conditions are in \u201cOur Own Measurements\u201d below.<\/p>\n<p><!-- \/lmw:lab-summary --><\/p>\n<h2>Overview<\/h2>\n<p>Efficient-Large-Model has released <code>LongLive-Plug-Wan2.1-T2V-14B-cfg<\/code>, a LoRA adapter for <code>Wan2.1-T2V-14B<\/code>. This adapter aims to distill Classifier-Free Guidance (CFG) into conditional-only video generation. This reduces the need to run a separate unconditional inference branch during the inference process. Note that this adapter does not provide a speedup in a few steps on its own; as it functions strictly as an adapter, using it requires the corresponding base model.<\/p>\n<h2>Specifications<\/h2>\n<ul>\n<li>Base model: <code>Wan-AI\/Wan2.1-T2V-14B<\/code><\/li>\n<li>Architecture: Video Diffusion DiT (Flow Matching framework)<\/li>\n<li>Base model specifications (14B):<\/li>\n<\/ul>\n<div class=\"lmw-table-scroll\" tabindex=\"0\" style=\"overflow-x:auto;-webkit-overflow-scrolling:touch;max-width:100%;\">\n<p class=\"lmw-table-hint\" style=\"margin:0 0 4px;font-size:0.85em;opacity:0.7;\">\u2192 Scroll horizontally to see all columns<\/p>\n<table style=\"width:max-content;min-width:100%;border-collapse:collapse;\">\n<thead>\n<tr>\n<th>Model<\/th>\n<th>Dimension<\/th>\n<th>Input Dimension<\/th>\n<th>Output Dimension<\/th>\n<th>Feedforward Dimension<\/th>\n<th>Frequency Dimension<\/th>\n<th>Number of Heads<\/th>\n<th>Number of Layers<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>14B<\/td>\n<td>5120<\/td>\n<td>16<\/td>\n<td>16<\/td>\n<td>13824<\/td>\n<td>256<\/td>\n<td>40<\/td>\n<td>40<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<ul>\n<li>Output resolution: Supports 480P and 720P<\/li>\n<li>Distribution format: <code>safetensors<\/code> (PEFT\/LoRA)<\/li>\n<li>License: <code>apache-2.0<\/code><\/li>\n<li>Recommended settings: It is recommended to use this in combination with the corresponding <code>few-step LoRA<\/code>. The recommended weight ratio is <code>few-step : CFG = 1 : 0.5<\/code>. However, this refers to the adapter weight ratio, not the CFG scale itself during inference.<\/li>\n<\/ul>\n<h2>Performance and Quality<\/h2>\n<p>The base model targeted by this adapter, <code>Wan2.1-T2V-14B<\/code>, is reported to outperform open-source and commercial state-of-the-art (SOTA) models across multiple benchmarks. According to the model card, evaluations were conducted using 1,035 internal prompts across 14 major dimensions and 26 sub-dimensions, confirming superior performance compared to existing models.<\/p>\n<p>Furthermore, manual evaluations with Prompt Extension applied show that it yields better results than existing open-source and closed-source models. The base model excels in its ability to generate high-quality visuals and notable motion dynamics, and is also characterized as being the only video model capable of generating text in both Chinese and English.<\/p>\n<h2>Strengths and Use Cases<\/h2>\n<p>This adapter excels at distilling Classifier-Free Guidance (CFG) into conditional-only generation during the video generation process of the base model, <code>Wan2.1-T2V-14B<\/code>. This makes it possible to eliminate the overhead of running a separate unconditional branch during inference.<\/p>\n<p>The base model, <code>Wan2.1-T2V-14B<\/code>, excels in <code>text-to-video<\/code> tasks at generating high-quality visuals and dynamic motion. It also has the capability to generate both Chinese and English text within videos.<\/p>\n<p><!-- lmw:files --><\/p>\n<h2>Distributed Files<\/h2>\n<p><em>Weight files published in <a href=\"https:\/\/huggingface.co\/Efficient-Large-Model\/LongLive-Plug-Wan2.1-T2V-14B-cfg\/tree\/main\">Efficient-Large-Model\/LongLive-Plug-Wan2.1-T2V-14B-cfg<\/a>, listed by this site from the Hugging Face API. Sizes are the actual file sizes.<\/em><\/p>\n<div class=\"lmw-table-scroll\" tabindex=\"0\" style=\"overflow-x:auto;-webkit-overflow-scrolling:touch;max-width:100%;\">\n<table style=\"width:max-content;min-width:100%;border-collapse:collapse;\">\n<thead>\n<tr>\n<th>File<\/th>\n<th>Size<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>adapter_model.safetensors<\/code><\/td>\n<td>2.45GB<\/td>\n<\/tr>\n<tr>\n<td><code>generator_lora.pt<\/code><\/td>\n<td>2.45GB<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p><!-- \/lmw:files --><\/p>\n<h2>How to Get It<\/h2>\n<p>This adapter is available from the following repository:<\/p>\n<ul>\n<li>Repository: <code>Efficient-Large-Model\/LongLive-Plug-Wan2.1-T2V-14B-cfg<\/code><\/li>\n<li>Distribution format: <code>safetensors<\/code><\/li>\n<li>Supported library: <code>peft<\/code><\/li>\n<\/ul>\n<p>Note that using this adapter requires the corresponding base model, <code>Wan-AI\/Wan2.1-T2V-14B<\/code>. Additionally, the publisher has released a <code>few-step LoRA<\/code> intended to be used in combination with it, and using them together is recommended.<\/p>\n<p><!-- lmw:runnability --><\/p>\n<h2>Can You Run It Locally?<\/h2>\n<p>The publisher distributes this model as safetensors.<\/p>\n<p><strong>License \u2014 <code>apache-2.0<\/code> (Commercial use allowed):<\/strong> Permits commercial use, modification and redistribution. Redistribution requires including the license and stating changes; includes a patent grant.<\/p>\n<p><em>Compiled by this site&#8217;s code from the published formats and the license field. License summaries are not legal advice \u2014 check the publisher&#8217;s original terms before relying on them.<\/em><\/p>\n<p><!-- \/lmw:runnability --><\/p>\n<p><!-- lmw:lab --><\/p>\n<h2>Our Own Measurements<\/h2>\n<p>Generated by us \u2014 not samples copied from the model card. We cannot run video models on our own server (no GPU), so we generated on a rented cloud GPU (conditions below). How we measure, and the results for every model: <a href=\"https:\/\/localmodelwatch.tsuchitsuchi.com\/en\/observations-en\/\">Our Measurements<\/a>.<\/p>\n<h3>Video We Generated (Cloud GPU)<\/h3>\n<p><a href=\"https:\/\/huggingface.co\/Efficient-Large-Model\/LongLive-Plug-Wan2.1-T2V-14B-cfg\">Efficient-Large-Model\/LongLive-Plug-Wan2.1-T2V-14B-cfg<\/a> (apache-2.0 license) is a LoRA adapter and does not run on its own, so we merged it into the base model <a href=\"https:\/\/huggingface.co\/Wan-AI\/Wan2.1-T2V-14B-Diffusers\">Wan-AI\/Wan2.1-T2V-14B-Diffusers<\/a> (apache-2.0 license) in the combination the publisher recommends (LongLive-Plug-Wan2.1-T2V-14B-few-step at weight 1.0, LongLive-Plug-Wan2.1-T2V-14B-cfg at weight 0.5) and generated with 4 steps and guidance scale 1.0. We set the sampler to match the publisher&#8217;s inference code (<a href=\"https:\/\/github.com\/NVlabs\/LongLive\/blob\/fb16a879f46e604df4a0ca48ce2bf45adfa90352\/LongLive-Plug\/inference.py\">LongLive-Plug inference.py<\/a>): UniPC with shift 5.0 (diffusers&#8217; UniPCMultistepScheduler). The publisher says to use this adapter together with <a href=\"https:\/\/huggingface.co\/Efficient-Large-Model\/LongLive-Plug-Wan2.1-T2V-14B-few-step\">LongLive-Plug-Wan2.1-T2V-14B-few-step<\/a>, so we merged both, and the same videos also appear in that adapter&#8217;s article. We ran diffusers&#8217; <code>WanPipeline<\/code> (diffusers 0.40.0) and did not run any code from the publisher. The LoRA was merged by our own code: we map the original Wan layer names to diffusers&#8217; names and add weight \u00d7 (alpha \/ r) \u00d7 BA to each weight. This mapping is our interpretation, not something the publisher documents; we only confirmed that every layer name and shape matched.<\/p>\n<p>Conditions: NVIDIA L40S (VRAM 44GB) on Modal, weights in BF16 (VAE in FP32), 832\u00d7480 pixels, 81 frames at 16 fps (about 5.06 s), seed 0, two fixed prompts without people, logos or text, generated 2026-10-02 (JST). Not selected \u2014 each clip is the first output. To fit our server&#8217;s upload limit we re-encoded each clip as H.264 (under 12.0 MB), so fine detail may be softer than the raw output.<\/p>\n<p><strong>Prompt: \u201ca small red paper boat drifting down a clear forest stream, sunlight flickering through the leaves, gentle ripples, realistic\u201d<\/strong><\/p>\n<p>Without the LoRA (base model, same 4 steps), 50 s to generate<\/p>\n<p><video controls preload=\"metadata\" playsinline src=\"https:\/\/localmodelwatch.tsuchitsuchi.com\/wp-content\/uploads\/2026\/10\/lmw-lab-202609291612_hf_model-Efficient-Large-Model-LongLive-Plug-Wan2-1-T2V-14B-base-boat-1.mp4\"><\/video><\/p>\n<p>With the LoRA, 51 s to generate<\/p>\n<p><video controls preload=\"metadata\" playsinline src=\"https:\/\/localmodelwatch.tsuchitsuchi.com\/wp-content\/uploads\/2026\/10\/lmw-lab-202609291612_hf_model-Efficient-Large-Model-LongLive-Plug-Wan2-1-T2V-14B-lora-boat-1.mp4\"><\/video><\/p>\n<p><strong>Prompt: \u201ctime-lapse of white clouds rolling over snowy mountain peaks at sunrise, golden light, wide shot\u201d<\/strong><\/p>\n<p>Without the LoRA (base model, same 4 steps), 51 s to generate<\/p>\n<p><video controls preload=\"metadata\" playsinline src=\"https:\/\/localmodelwatch.tsuchitsuchi.com\/wp-content\/uploads\/2026\/10\/lmw-lab-202609291612_hf_model-Efficient-Large-Model-LongLive-Plug-Wan2-1-T2V-14B-base-clouds-1.mp4\"><\/video><\/p>\n<p>With the LoRA, 52 s to generate<\/p>\n<p><video controls preload=\"metadata\" playsinline src=\"https:\/\/localmodelwatch.tsuchitsuchi.com\/wp-content\/uploads\/2026\/10\/lmw-lab-202609291612_hf_model-Efficient-Large-Model-LongLive-Plug-Wan2-1-T2V-14B-lora-clouds-1.mp4\"><\/video><\/p>\n<div class=\"lmw-table-scroll\" tabindex=\"0\" style=\"overflow-x:auto;-webkit-overflow-scrolling:touch;max-width:100%;\">\n<table style=\"width:max-content;min-width:100%;border-collapse:collapse;\">\n<thead>\n<tr>\n<th>Item<\/th>\n<th>Result<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>VRAM after loading the model (BF16, text encoder already released)<\/td>\n<td>27.3GB<\/td>\n<\/tr>\n<tr>\n<td>Peak VRAM while generating<\/td>\n<td>35.5GB<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>Generation times are for a rented cloud NVIDIA L40S and are not a guide to your own GPU; the text encoder runs first and is released before the video model loads, so the VRAM above does not include it. The \u201cwithout the LoRA\u201d clips use the same 4 steps for comparison only; the base model&#8217;s usual settings use many more steps with guidance, so they do not show what the base model can do.<\/p>\n<h4>Setup, Download and Run Steps (What We Actually Ran)<\/h4>\n<p>We split the work into two containers on Modal, both built from the Debian (slim) image with Python 3.12. The downloading container fetches only the listed files (configs, safetensors weights and the tokenizer) from Hugging Face at pinned revisions; the generating container has no network access. These are the packages we installed:<\/p>\n<pre><code class=\"language-bash\"># 1. Environment for downloading (no GPU)\npython -m pip install huggingface_hub\n\n# 2. Environment for generating (GPU, network blocked)\npython -m pip install torch diffusers transformers accelerate safetensors sentencepiece ftfy imageio-ffmpeg numpy\n<\/code><\/pre>\n<p>We then called <code>download(job)<\/code> in the first container and <code>run(job)<\/code> in the second one from the script below (<code>video_remote.py<\/code>, written by us; full text). Files go under <code>\/models\/&lt;dir&gt;<\/code>:<\/p>\n<pre><code class=\"language-python\">&quot;&quot;&quot;\nModal \u306e\u30b3\u30f3\u30c6\u30ca\u306e\u4e2d\u3067\u52d5\u304f\u3001\u52d5\u753b\u751f\u6210\u30e2\u30c7\u30eb\u306e\u751f\u6210(2026-10-01\u3001\u30e6\u30fc\u30b6\u30fc\u306e\u5224\u65ad)\u3002lmw\/lab\/gpu_modal.py \u306e\nvideo_download \/ video_run \u304b\u3089\u547c\u3070\u308c\u308b\u3002**\u6a19\u6e96\u30e9\u30a4\u30d6\u30e9\u30ea\u3060\u3051\u3092\u5148\u982d\u3067\u8aad\u307f**\u3001huggingface_hub\u30fbtorch\u30fbdiffusers \u306f\n\u5404\u95a2\u6570\u306e\u4e2d\u3067\u8aad\u3080(\u30b3\u30f3\u30c6\u30ca\u3054\u3068\u306b\u5165\u3063\u3066\u3044\u308b\u3082\u306e\u304c\u9055\u3046)\u3002\n\n\u3010\u914d\u5e03\u5143\u306e\u30b3\u30fc\u30c9\u306f\u52d5\u304b\u3055\u306a\u3044\u3011diffusers\u30fbtransformers \u306e\u516c\u958b\u30d1\u30c3\u30b1\u30fc\u30b8\u3060\u3051\u3067\u8aad\u307f\u8fbc\u3080\u3002\u91cd\u307f\u306f safetensors \u3060\u3051\u3067\u3001\nHugging Face \u306e\u30ea\u30dd\u30b8\u30c8\u30ea\u306e\u30b3\u30fc\u30c9\u3092\u8aad\u307f\u8fbc\u3080\u8a2d\u5b9a\u306f\u4f7f\u308f\u306a\u3044\u3002LoRA \u306f\u5f53\u30b5\u30a4\u30c8\u306e\u30b3\u30fc\u30c9(merge_lora)\u304c\u3001\u540d\u524d\u306e\u5bfe\u5fdc\u8868\u3068\n\u5f62\u3092\u7167\u5408\u3057\u306a\u304c\u3089\u5143\u306e\u91cd\u307f\u306b\u8db3\u3057\u8fbc\u3080(\u914d\u5e03\u5143\u306e\u8aad\u307f\u8fbc\u307f\u51e6\u7406\u306f\u4f7f\u308f\u306a\u3044)\u3002\n\n\u30102\u3064\u306e\u30b3\u30f3\u30c6\u30ca\u306b\u5206\u3051\u308b\u3011(lmw\/lab\/remote_code_remote.py \u3068\u540c\u3058)\n- download: GPU \u306e\u7121\u3044\u30b3\u30f3\u30c6\u30ca\u30fb\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u3042\u308a\u3002Hugging Face \u304b\u3089\u3001\u7248\u3092\u56fa\u5b9a\u3057\u3066\u6c7a\u307e\u3063\u305f\u30d5\u30a1\u30a4\u30eb\u3060\u3051\u3092\u843d\u3068\u3059\u3002\n- run: GPU \u306e\u30b3\u30f3\u30c6\u30ca\u30fb**\u30cd\u30c3\u30c8\u30ef\u30fc\u30af\u906e\u65ad**\u30fbModal \u306e\u6a5f\u80fd\u3082\u4f7f\u3048\u306a\u3044\u30fbVolume \u306f\u8aad\u307f\u53d6\u308a\u5c02\u7528\u3002\n\n\u3010VRAM \u3092\u7bc0\u7d04\u3059\u308b\u9806\u756a\u3011\u30c6\u30ad\u30b9\u30c8\u30a8\u30f3\u30b3\u30fc\u30c0(UMT5-XXL \u306f 11GB)\u3067\u30d7\u30ed\u30f3\u30d7\u30c8\u3092\u5148\u306b\u5168\u90e8\u57cb\u3081\u8fbc\u307f\u306b\u3057\u3066\u304b\u3089\u6368\u3066\u3001\n\u305d\u306e\u5f8c\u3067\u52d5\u753b\u306e\u672c\u4f53(transformer)\u3068 VAE \u3092\u8aad\u3080\u30022\u3064\u3092\u540c\u6642\u306b GPU \u306b\u8f09\u305b\u306a\u3044\u306e\u3067\u3001\u5b89\u3044 GPU \u306b\u53ce\u307e\u308b\u3002\n\n\u3010\u7d50\u679c\u306e\u8fd4\u3057\u65b9\u3011run \u306f\u751f\u6210\u5668\u3067\u3001\u52d5\u753b\u306e\u30d0\u30a4\u30c8\u5217\u3092 CHUNK_BYTES \u305a\u3064(kind: &quot;chunk&quot;)\u3001\u6700\u5f8c\u306b\u8a18\u9332(kind: &quot;record&quot;)\u3092\u8fd4\u3059\u3002\nModal \u306f 2MiB \u3092\u8d85\u3048\u308b\u623b\u308a\u5024\u3092\u81ea\u5206\u306e API \u3067\u9810\u3051\u308b\u304c\u3001\u751f\u6210\u306e\u30b3\u30f3\u30c6\u30ca\u306f Modal \u306e\u6a5f\u80fd\u3092\u906e\u65ad\u3057\u3066\u3044\u308b\n(restrict_modal_access)\u306e\u3067\u65ad\u3089\u308c\u308b(2026-10-02\u300114B \u306e4\u672c\u3092\u4f5c\u308a\u7d42\u3048\u305f\u5f8c\u306b 401 \u3067\u5168\u3066\u5931\u3063\u305f)\u30021\u56de\u306e\u623b\u308a\u5024\u3092\u5c0f\u3055\u304f\u4fdd\u3064\u3002\n\n\u3010\u8cbb\u7528\u3092\u6291\u3048\u308b\u3011\u540c\u3058\u8aad\u307f\u8fbc\u307f\u306e\u307e\u307e\u3001LoRA \u3092\u8db3\u3059\u524d(\u5143\u306e\u30e2\u30c7\u30eb)\u3068\u8db3\u3057\u305f\u5f8c\u3092\u7d9a\u3051\u3066\u751f\u6210\u3059\u308b(\u8aad\u307f\u8fbc\u307f\u306f1\u56de)\u3002\n\u52d5\u753b\u306f WordPress \u306e\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u306e\u4e0a\u9650\u306b\u53ce\u307e\u308b\u3088\u3046 H.264 \u3067\u5727\u7e2e\u3059\u308b(MAX_BYTES \u3092\u8d85\u3048\u305f\u3089\u753b\u8cea\u3092\u4e0b\u3052\u3066\u4f5c\u308a\u76f4\u3059)\u3002\n\n\u8a18\u4e8b\u57f7\u7b46\u7528\u306e LLM \u306f\u547c\u3070\u306a\u3044\u3002\n&quot;&quot;&quot;\nimport hashlib\nimport json\nimport os\nimport platform\nimport subprocess\nimport time\nfrom datetime import datetime, timezone\n\nMOUNT = &quot;\/models&quot;\nPYTHON_VERSION = &quot;3.12&quot;\nDOWNLOAD_PACKAGES = (&quot;huggingface_hub&quot;,)\n# diffusers \u306e Wan \u306e\u30d1\u30a4\u30d7\u30e9\u30a4\u30f3\u304c\u4f7f\u3046\u3082\u306e(ftfy \u306f\u30d7\u30ed\u30f3\u30d7\u30c8\u306e\u6574\u5f62\u3001imageio-ffmpeg \u306f H.264 \u306e\u66f8\u304d\u51fa\u3057\u306b\u4f7f\u3046)\nRUN_PACKAGES = (&quot;torch&quot;, &quot;diffusers&quot;, &quot;transformers&quot;, &quot;accelerate&quot;, &quot;safetensors&quot;, &quot;sentencepiece&quot;, &quot;ftfy&quot;,\n                &quot;imageio-ffmpeg&quot;, &quot;numpy&quot;)\n# \u843d\u3068\u3057\u3066\u3088\u3044\u30d5\u30a1\u30a4\u30eb(pickle \u306e .bin \/ .pt \/ .ckpt \u306f\u843d\u3068\u3055\u306a\u3044)\nALLOWED_EXTS = (&quot;.json&quot;, &quot;.safetensors&quot;, &quot;.model&quot;, &quot;.txt&quot;)\n\n# \u5143\u306e Wan \u306e\u5c64\u306e\u540d\u524d(LoRA \u304c\u4f7f\u3046)\u2192 diffusers \u306e WanTransformer3DModel \u306e\u5c64\u306e\u540d\u524d\u3002\n# diffusers \u306e\u5909\u63db\u30b9\u30af\u30ea\u30d7\u30c8(scripts\/convert_wan_to_diffusers.py)\u3068\u540c\u3058\u5bfe\u5fdc\nWAN_LORA_MODULES = {\n    &quot;self_attn.q&quot;: &quot;attn1.to_q&quot;, &quot;self_attn.k&quot;: &quot;attn1.to_k&quot;, &quot;self_attn.v&quot;: &quot;attn1.to_v&quot;,\n    &quot;self_attn.o&quot;: &quot;attn1.to_out.0&quot;,\n    &quot;cross_attn.q&quot;: &quot;attn2.to_q&quot;, &quot;cross_attn.k&quot;: &quot;attn2.to_k&quot;, &quot;cross_attn.v&quot;: &quot;attn2.to_v&quot;,\n    &quot;cross_attn.o&quot;: &quot;attn2.to_out.0&quot;,\n    &quot;ffn.0&quot;: &quot;ffn.net.0.proj&quot;, &quot;ffn.2&quot;: &quot;ffn.net.2&quot;,\n}\n# 1\u56de\u306b\u8fd4\u3059\u30d0\u30a4\u30c8\u6570(Modal \u304c\u81ea\u5206\u306e API \u306b\u9810\u3051\u305a\u306b\u305d\u306e\u307e\u307e\u8fd4\u305b\u308b 2MiB \u3088\u308a\u5341\u5206\u5c0f\u3055\u304f)\nCHUNK_BYTES = 1024 * 1024\nLORA_PREFIXES = (&quot;base_model.model.&quot;, &quot;diffusion_model.&quot;, &quot;model.&quot;)\n# \u751f\u6210\u306b\u4f7f\u3046\u30c7\u30d0\u30a4\u30b9\u3002Modal \u3067\u306f\u5e38\u306b cuda(\u5f53\u30b5\u30a4\u30c8\u306e\u8a55\u4fa1\u3067\u3001\u5c0f\u3055\u306a\u30e2\u30c7\u30eb\u3092 CPU \u3067\u901a\u3059\u3068\u304d\u3060\u3051 cpu \u306b\u3059\u308b)\nDEVICE = &quot;cuda&quot;\n\ndef installed_packages() -&gt; list[str]:\n    from importlib import metadata\n    seen = {}\n    for dist in metadata.distributions():\n        name = dist.metadata[&quot;Name&quot;]\n        if name and name.lower() not in seen:\n            seen[name.lower()] = f&quot;{name}=={dist.version}&quot;\n    return sorted(seen.values(), key=str.lower)\n\ndef _log(t0: float, message: str) -&gt; None:\n    print(f&quot; {message}&quot;, flush=True)\n\ndef _sha256(path: str) -&gt; str:\n    h = hashlib.sha256()\n    with open(path, &quot;rb&quot;) as f:\n        for chunk in iter(lambda: f.read(1 &lt;&lt; 20), b&quot;&quot;):\n            h.update(chunk)\n    return h.hexdigest()\n\ndef download(job: dict) -&gt; dict:\n    &quot;&quot;&quot;\n    job: {&quot;dir&quot;, &quot;base&quot;: {&quot;repo&quot;, &quot;revision&quot;, &quot;files&quot;}, &quot;loras&quot;: [{&quot;repo&quot;, &quot;revision&quot;, &quot;file&quot;}]}\u3002\n    \u5143\u306e\u30e2\u30c7\u30eb\u306f &lt;dir&gt;\/base\u3001LoRA \u306f &lt;dir&gt;\/lora&lt;i&gt;\/ \u306b\u7f6e\u304f\u3002\u623b\u308a\u5024: {&quot;bytes&quot;, &quot;seconds&quot;, &quot;packages&quot;, &quot;lora_sha256&quot;}\u3002\n    &quot;&quot;&quot;\n    from huggingface_hub import hf_hub_download\n    t0 = time.time()\n    base_dir = os.path.join(MOUNT, job[&quot;dir&quot;])\n    total = 0\n    targets = [(job[&quot;base&quot;][&quot;repo&quot;], job[&quot;base&quot;][&quot;revision&quot;], name, os.path.join(base_dir, &quot;base&quot;))\n               for name in job[&quot;base&quot;][&quot;files&quot;]]\n    targets += [(lora[&quot;repo&quot;], lora[&quot;revision&quot;], lora[&quot;file&quot;], os.path.join(base_dir, f&quot;lora{i}&quot;))\n                for i, lora in enumerate(job.get(&quot;loras&quot;) or [])]\n    for repo, revision, name, dest in targets:\n        if not name.endswith(ALLOWED_EXTS) or &quot;..&quot; in name.split(&quot;\/&quot;):\n            raise ValueError(f&quot;\u843d\u3068\u3055\u306a\u3044\u7a2e\u985e\u306e\u30d5\u30a1\u30a4\u30eb\u3067\u3059: {name}&quot;)\n        path = hf_hub_download(repo, name, revision=revision, local_dir=dest)\n        total += os.path.getsize(path)\n    lora_sha = [_sha256(os.path.join(base_dir, f&quot;lora{i}&quot;, lora[&quot;file&quot;]))\n                for i, lora in enumerate(job.get(&quot;loras&quot;) or [])]\n    seconds = round(time.time() - t0)\n    _log(t0, f&quot;\u30c0\u30a6\u30f3\u30ed\u30fc\u30c9 {total \/ 1024 ** 3:.1f}GB\u30fb{seconds}\u79d2&quot;)\n    return {&quot;bytes&quot;: int(total), &quot;seconds&quot;: int(seconds), &quot;packages&quot;: installed_packages(), &quot;lora_sha256&quot;: lora_sha}\n\ndef _lora_pairs(state: dict) -&gt; dict:\n    &quot;&quot;&quot;{\u5143\u306e\u5c64\u306e\u540d\u524d: {&quot;A&quot;, &quot;B&quot;, &quot;alpha&quot;?}}\u3002\u540d\u524d\u306e\u982d(base_model.model. \u7b49)\u3092\u5916\u3057\u3001A \u3068 B \u306e\u63c3\u308f\u306a\u3044\u5c64\u306f\u65ad\u308b\u3002&quot;&quot;&quot;\n    pairs: dict = {}\n    for key, tensor in state.items():\n        name = key\n        for prefix in LORA_PREFIXES:\n            if name.startswith(prefix):\n                name = name[len(prefix):]\n                break\n        if name.endswith(&quot;.lora_A.weight&quot;):\n            pairs.setdefault(name[:-len(&quot;.lora_A.weight&quot;)], {})[&quot;A&quot;] = tensor\n        elif name.endswith(&quot;.lora_B.weight&quot;):\n            pairs.setdefault(name[:-len(&quot;.lora_B.weight&quot;)], {})[&quot;B&quot;] = tensor\n        elif name.endswith(&quot;.alpha&quot;):\n            pairs.setdefault(name[:-len(&quot;.alpha&quot;)], {})[&quot;alpha&quot;] = float(tensor.item())\n        else:\n            raise ValueError(f&quot;LoRA \u306e\u91cd\u307f\u3067\u306f\u306a\u3044\u540d\u524d\u3067\u3059: {key}&quot;)\n    broken = [n for n, p in pairs.items() if &quot;A&quot; not in p or &quot;B&quot; not in p]\n    if broken:\n        raise ValueError(f&quot;A \u3068 B \u304c\u63c3\u308f\u306a\u3044\u5c64\u304c\u3042\u308a\u307e\u3059: {broken[:5]}&quot;)\n    return pairs\n\ndef diffusers_module_name(name: str) -&gt; str:\n    &quot;&quot;&quot;blocks.12.self_attn.q \u2192 blocks.12.attn1.to_q\u3002\u5bfe\u5fdc\u8868\u306b\u7121\u3044\u5c64\u306f\u65ad\u308b(\u63a8\u6e2c\u3067\u5f53\u3066\u306a\u3044)\u3002&quot;&quot;&quot;\n    parts = name.split(&quot;.&quot;)\n    if len(parts) &lt; 4 or parts[0] != &quot;blocks&quot; or not parts[1].isdigit():\n        raise ValueError(f&quot;\u5bfe\u5fdc\u8868\u306b\u7121\u3044\u5c64\u3067\u3059: {name}&quot;)\n    tail = &quot;.&quot;.join(parts[2:])\n    if tail not in WAN_LORA_MODULES:\n        raise ValueError(f&quot;\u5bfe\u5fdc\u8868\u306b\u7121\u3044\u5c64\u3067\u3059: {name}&quot;)\n    return f&quot;blocks.{parts[1]}.{WAN_LORA_MODULES[tail]}&quot;\n\ndef merge_lora(transformer, path: str, weight: float, alpha: float | None, rank: int | None) -&gt; dict:\n    &quot;&quot;&quot;\n    LoRA \u3092\u5143\u306e\u91cd\u307f\u306b\u8db3\u3057\u8fbc\u3080: W \u2190 W + weight \u00d7 (alpha \/ r) \u00d7 (B @ A)\u3002alpha \u3068 r \u306f\u914d\u5e03\u5143\u306e adapter_config.json \u306e\u5024\u3092\n    \u30db\u30b9\u30c8\u5074\u304c\u6e21\u3059(\u91cd\u307f\u306e\u30d5\u30a1\u30a4\u30eb\u306b alpha \u304c\u3042\u308c\u3070\u305d\u3061\u3089\u3092\u4f7f\u3046)\u3002\u8db3\u3057\u8fbc\u307f\u306f float32 \u3067\u8a08\u7b97\u3057\u3066\u304b\u3089\u5143\u306e\u578b\u306b\u623b\u3059\u3002\n    \u5168\u3066\u306e\u5c64\u304c\u5bfe\u5fdc\u8868\u3067\u898b\u3064\u304b\u308a\u3001\u5f62\u304c\u4e00\u81f4\u3059\u308b\u3053\u3068\u3092\u78ba\u304b\u3081\u308b(1\u3064\u3067\u3082\u5916\u308c\u305f\u3089\u65ad\u308b)\u3002\n    &quot;&quot;&quot;\n    import torch\n    from safetensors.torch import load_file\n    pairs = _lora_pairs(load_file(path))\n    merged = 0\n    for name, p in sorted(pairs.items()):\n        module = transformer.get_submodule(diffusers_module_name(name))\n        a, b = p[&quot;A&quot;].float(), p[&quot;B&quot;].float()\n        r = a.shape[0]\n        if rank and r != rank:\n            raise ValueError(f&quot;{name}: \u30e9\u30f3\u30af {r} \u304c adapter_config.json \u306e {rank} \u3068\u9055\u3044\u307e\u3059&quot;)\n        scale = weight * ((p.get(&quot;alpha&quot;) or alpha or r) \/ r)\n        w = module.weight\n        delta = (b.to(w.device) @ a.to(w.device)) * scale\n        if tuple(delta.shape) != tuple(w.shape):\n            raise ValueError(f&quot;{name}: \u5f62 {tuple(delta.shape)} \u304c\u5143\u306e\u91cd\u307f {tuple(w.shape)} \u3068\u9055\u3044\u307e\u3059&quot;)\n        with torch.no_grad():\n            w.copy_((w.float() + delta).to(w.dtype))\n        merged += 1\n    return {&quot;modules&quot;: merged, &quot;weight&quot;: weight, &quot;scale&quot;: round(weight * ((alpha or rank or 1) \/ (rank or 1)), 6)}\n\ndef encode_mp4(frames, fps: int, path: str, max_bytes: int) -&gt; dict:\n    &quot;&quot;&quot;\n    0\u301c1 \u306e RGB \u306e\u30b3\u30de(F, H, W, 3)\u3092 H.264(yuv420p)\u306e mp4 \u306b\u3059\u308b\u3002max_bytes \u3092\u8d85\u3048\u305f\u3089\u3001\u30d3\u30c3\u30c8\u30ec\u30fc\u30c8\u306e\u4e0a\u9650\u3092\n    \u4e0b\u3052\u3066\u4f5c\u308a\u76f4\u3059(3\u56de\u307e\u3067)\u3002\u623b\u308a\u5024: \u5b9f\u969b\u306b\u4f7f\u3063\u305f ffmpeg \u306e\u5f15\u6570\u3068\u5927\u304d\u3055\u3002\n    &quot;&quot;&quot;\n    import imageio_ffmpeg\n    import numpy as np\n    pixels = (np.clip(frames, 0.0, 1.0) * 255).round().astype(np.uint8)\n    count, height, width = pixels.shape[0], pixels.shape[1], pixels.shape[2]\n    duration = count \/ fps\n    # \u4e0a\u9650\u306e\u5927\u304d\u3055\u306e 85% \u306b\u53ce\u307e\u308b\u30d3\u30c3\u30c8\u30ec\u30fc\u30c8(\u97f3\u58f0\u306a\u3057)\n    kbps = int(max_bytes * 8 * 0.85 \/ duration \/ 1000)\n    for attempt, crf in enumerate((18, 22, 26)):\n        rate = int(kbps * (0.8 ** attempt))\n        args = [&quot;-y&quot;, &quot;-f&quot;, &quot;rawvideo&quot;, &quot;-pix_fmt&quot;, &quot;rgb24&quot;, &quot;-s&quot;, f&quot;{width}x{height}&quot;, &quot;-r&quot;, str(fps), &quot;-i&quot;, &quot;-&quot;,\n                &quot;-an&quot;, &quot;-c:v&quot;, &quot;libx264&quot;, &quot;-preset&quot;, &quot;slow&quot;, &quot;-crf&quot;, str(crf), &quot;-maxrate&quot;, f&quot;{rate}k&quot;,\n                &quot;-bufsize&quot;, f&quot;{rate * 2}k&quot;, &quot;-pix_fmt&quot;, &quot;yuv420p&quot;, &quot;-movflags&quot;, &quot;+faststart&quot;, path]\n        proc = subprocess.run([imageio_ffmpeg.get_ffmpeg_exe(), *args], input=pixels.tobytes(),\n                              capture_output=True, timeout=600)\n        if proc.returncode != 0:\n            raise RuntimeError(f&quot;ffmpeg \u304c\u5931\u6557\u3057\u307e\u3057\u305f: {proc.stderr.decode(errors='replace')[-400:]}&quot;)\n        size = os.path.getsize(path)\n        if size &lt;= max_bytes:\n            return {&quot;ffmpeg_args&quot;: [&quot;ffmpeg&quot;, *args[:-1], os.path.basename(path)], &quot;bytes&quot;: size,\n                    &quot;frames&quot;: int(count), &quot;width&quot;: int(width), &quot;height&quot;: int(height), &quot;fps&quot;: int(fps),\n                    &quot;duration&quot;: round(duration, 2)}\n    raise ValueError(f&quot;\u52d5\u753b\u3092 {max_bytes} \u30d0\u30a4\u30c8\u4ee5\u4e0b\u306b\u5727\u7e2e\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f&quot;)\n\ndef run(job: dict):\n    &quot;&quot;&quot;\n    job: {&quot;dir&quot;, &quot;pipeline&quot;, &quot;settings&quot;: {height, width, num_frames, fps, steps, guidance, flow_shift?},\n          &quot;seed&quot;, &quot;prompts&quot;: [{&quot;id&quot;, &quot;en&quot;}], &quot;loras&quot;: [{&quot;file&quot;, &quot;weight&quot;, &quot;alpha&quot;, &quot;rank&quot;}], &quot;compare_base&quot;,\n          &quot;max_bytes&quot;}\u3002\n    \u751f\u6210\u5668: {&quot;kind&quot;: &quot;chunk&quot;, &quot;id&quot;, &quot;index&quot;, &quot;data&quot;: bytes} \u3092\u52d5\u753b\u3054\u3068\u306b\u9806\u306b\u8fd4\u3057\u3001\u6700\u5f8c\u306b\n    {&quot;kind&quot;: &quot;record&quot;, ...\u8a18\u9332\u306e\u4e00\u90e8(\u79d2\u6570\u30fbVRAM\u30fb\u7248\u3002\u52d5\u753b\u306e\u4e2d\u8eab\u306f\u542b\u307e\u306a\u3044)} \u3092\u8fd4\u3059\u3002\n    &quot;&quot;&quot;\n    import diffusers\n    import numpy as np\n    import torch\n    import transformers\n    os.environ[&quot;HF_HUB_OFFLINE&quot;] = &quot;1&quot;\n    os.environ[&quot;TRANSFORMERS_OFFLINE&quot;] = &quot;1&quot;\n    os.environ[&quot;HF_HUB_DISABLE_TELEMETRY&quot;] = &quot;1&quot;\n    t0 = time.time()\n    base_dir = os.path.join(MOUNT, job[&quot;dir&quot;])\n    model_dir = os.path.join(base_dir, &quot;base&quot;)\n    settings = job[&quot;settings&quot;]\n    guidance = float(settings[&quot;guidance&quot;])\n    cuda = DEVICE == &quot;cuda&quot;\n    gpu = torch.cuda.get_device_name(0) if cuda else &quot;cpu&quot;\n    _log(t0, f&quot;GPU: {gpu}\u30fbdiffusers {diffusers.__version__}\u30fbtorch {torch.__version__}&quot;)\n    record = {&quot;gpu&quot;: gpu, &quot;vram_total&quot;: int(torch.cuda.get_device_properties(0).total_memory) if cuda else 0,\n              &quot;diffusers&quot;: str(diffusers.__version__), &quot;transformers&quot;: str(transformers.__version__),\n              &quot;torch&quot;: str(torch.__version__), &quot;dtype&quot;: &quot;bfloat16&quot;, &quot;vae_dtype&quot;: &quot;float32&quot;,\n              &quot;packages&quot;: installed_packages(), &quot;python&quot;: platform.python_version(),\n              &quot;measured_at&quot;: datetime.now(timezone.utc).isoformat()}\n    pipeline_cls = getattr(diffusers, job[&quot;pipeline&quot;])\n\n    # 1. \u30d7\u30ed\u30f3\u30d7\u30c8\u3092\u57cb\u3081\u8fbc\u307f\u306b\u3059\u308b(\u30c6\u30ad\u30b9\u30c8\u30a8\u30f3\u30b3\u30fc\u30c0\u3060\u3051\u3092 GPU \u306b\u8f09\u305b\u3001\u7d42\u308f\u3063\u305f\u3089\u6368\u3066\u308b)\n    with open(os.path.join(model_dir, &quot;model_index.json&quot;), encoding=&quot;utf-8&quot;) as f:\n        index = json.load(f)\n    skip_models = {name: None for name, spec in index.items()\n                   if isinstance(spec, list) and name not in (&quot;text_encoder&quot;, &quot;tokenizer&quot;, &quot;scheduler&quot;)}\n    text_pipe = pipeline_cls.from_pretrained(model_dir, torch_dtype=torch.bfloat16, use_safetensors=True,\n                                             local_files_only=True, **skip_models)\n    text_pipe.text_encoder.to(DEVICE)\n    embeds = {}\n    with torch.no_grad():\n        for p in job[&quot;prompts&quot;]:\n            # max_sequence_length \u306f\u30d1\u30a4\u30d7\u30e9\u30a4\u30f3\u306e __call__ \u306e\u65e2\u5b9a(512\u3002\u5143\u306e Wan \u3082 512)\u306b\u5408\u308f\u305b\u308b\u3002\n            # encode_prompt \u306e\u65e2\u5b9a\u306f 226 \u3067\u3001\u305d\u306e\u307e\u307e\u3060\u3068\u6a19\u6e96\u306e\u547c\u3073\u51fa\u3057\u3068\u9055\u3046\u57cb\u3081\u8fbc\u307f\u306b\u306a\u308b\n            pos, neg = text_pipe.encode_prompt(prompt=p[&quot;en&quot;], negative_prompt=&quot;&quot;, device=DEVICE,\n                                               do_classifier_free_guidance=guidance &gt; 1.0,\n                                               max_sequence_length=int(settings.get(&quot;max_sequence_length&quot;, 512)))\n            embeds[p[&quot;id&quot;]] = (pos.cpu(), None if neg is None else neg.cpu())\n    del text_pipe\n    if cuda:\n        torch.cuda.empty_cache()\n    record[&quot;encode_sec&quot;] = round(time.time() - t0)\n\n    # 2. \u672c\u4f53\u3068 VAE \u3092\u8aad\u3080(VAE \u306f float32\u3002diffusers \u306e Wan \u306e\u4f8b\u3068\u540c\u3058)\n    vae_cls = getattr(diffusers, index[&quot;vae&quot;][1])\n    vae = vae_cls.from_pretrained(model_dir, subfolder=&quot;vae&quot;, torch_dtype=torch.float32, use_safetensors=True,\n                                  local_files_only=True)\n    pipe = pipeline_cls.from_pretrained(model_dir, vae=vae, text_encoder=None, tokenizer=None,\n                                        torch_dtype=torch.bfloat16, use_safetensors=True, local_files_only=True)\n    if settings.get(&quot;flow_shift&quot;) is not None:\n        pipe.scheduler = type(pipe.scheduler).from_config(pipe.scheduler.config, flow_shift=float(settings[&quot;flow_shift&quot;]))\n    record[&quot;scheduler&quot;] = {&quot;class&quot;: type(pipe.scheduler).__name__,\n                           **{k: v for k, v in dict(pipe.scheduler.config).items()\n                              if k in (&quot;flow_shift&quot;, &quot;use_flow_sigmas&quot;, &quot;prediction_type&quot;, &quot;solver_order&quot;)}}\n    pipe.to(DEVICE)\n    if cuda:\n        torch.cuda.synchronize()\n    record[&quot;vram_loaded&quot;] = int(torch.cuda.memory_allocated()) if cuda else 0\n    record[&quot;load_sec&quot;] = round(time.time() - t0)\n    _log(t0, f&quot;\u8aad\u307f\u8fbc\u307f: VRAM {record['vram_loaded'] \/ 1024 ** 3:.1f}GB\u30fb{record['load_sec']}\u79d2&quot;)\n    if cuda:\n        torch.cuda.reset_peak_memory_stats()\n\n    def generate(group: str) -&gt; list[dict]:\n        out = []\n        for p in job[&quot;prompts&quot;]:\n            pos, neg = embeds[p[&quot;id&quot;]]\n            started = time.time()\n            generator = torch.Generator(&quot;cpu&quot;).manual_seed(int(job[&quot;seed&quot;]))\n            frames = pipe(prompt_embeds=pos.to(DEVICE),\n                          negative_prompt_embeds=None if neg is None else neg.to(DEVICE),\n                          height=int(settings[&quot;height&quot;]), width=int(settings[&quot;width&quot;]),\n                          num_frames=int(settings[&quot;num_frames&quot;]), num_inference_steps=int(settings[&quot;steps&quot;]),\n                          guidance_scale=guidance, generator=generator, output_type=&quot;np&quot;).frames[0]\n            if cuda:\n                torch.cuda.synchronize()\n            seconds = time.time() - started\n            frames = np.asarray(frames, dtype=np.float32)\n            if not np.isfinite(frames).all():\n                raise FloatingPointError(&quot;\u751f\u6210\u3057\u305f\u30b3\u30de\u306b\u6570\u3067\u306a\u3044\u5024\u304c\u3042\u308a\u307e\u3059&quot;)\n            # \u51e6\u7406\u306e\u8aa4\u308a(\u771f\u3063\u9ed2\u30fb\u4e00\u8272\u306e\u52d5\u753b)\u3092\u53d6\u308a\u8fbc\u307f\u5f79\u306e\u6a5f\u68b0\u306e\u691c\u67fb(lmw\/lab\/sanity.py)\u304c\u898b\u3064\u3051\u308b\u305f\u3081\u306e\u5024\n            stats = {&quot;pixel_mean&quot;: round(float(frames.mean()) * 255, 2), &quot;pixel_std&quot;: round(float(frames.std()) * 255, 2)}\n            path = os.path.join(&quot;\/tmp&quot;, f&quot;{group}-{p['id']}.mp4&quot;)\n            encoded = encode_mp4(frames, int(settings[&quot;fps&quot;]), path, int(job[&quot;max_bytes&quot;]))\n            with open(path, &quot;rb&quot;) as f:\n                raw = f.read()\n            blobs[f&quot;{group}-{p['id']}&quot;] = raw\n            out.append({&quot;id&quot;: f&quot;{group}-{p['id']}&quot;, &quot;prompt_id&quot;: p[&quot;id&quot;], &quot;group&quot;: group,\n                        &quot;seconds&quot;: round(seconds, 1), **encoded, **stats,\n                        &quot;sha256&quot;: hashlib.sha256(raw).hexdigest()})\n            _log(t0, f&quot;{group}\/{p['id']}: {encoded['frames']}\u30b3\u30de\u30fb\u751f\u6210 {seconds:.0f}\u79d2\u30fb{encoded['bytes'] \/ 1e6:.2f}MB&quot;)\n        return out\n\n    videos = []\n    blobs: dict[str, bytes] = {}\n    loras = job.get(&quot;loras&quot;) or []\n    # 3. LoRA \u3092\u8db3\u3059\u524d\u306e\u5143\u306e\u30e2\u30c7\u30eb(\u6bd4\u3079\u308b\u305f\u3081\u3002\u540c\u3058\u30d7\u30ed\u30f3\u30d7\u30c8\u30fb\u30b7\u30fc\u30c9\u30fb\u30b9\u30c6\u30c3\u30d7\u6570)\n    if loras and job.get(&quot;compare_base&quot;):\n        videos += generate(&quot;base&quot;)\n    # 4. LoRA \u3092\u8db3\u3057\u8fbc\u3093\u3067\u304b\u3089\u751f\u6210\u3059\u308b\n    merges = []\n    for i, lora in enumerate(loras):\n        path = os.path.join(base_dir, f&quot;lora{i}&quot;, lora[&quot;file&quot;])\n        merges.append(merge_lora(pipe.transformer, path, float(lora[&quot;weight&quot;]), lora.get(&quot;alpha&quot;), lora.get(&quot;rank&quot;)))\n        _log(t0, f&quot;LoRA {i}: {merges[-1]['modules']}\u5c64\u3092\u8db3\u3057\u8fbc\u307f\u307e\u3057\u305f(\u91cd\u307f {lora['weight']})&quot;)\n    if merges:\n        record[&quot;merges&quot;] = merges\n    videos += generate(&quot;lora&quot; if loras else &quot;model&quot;)\n    record[&quot;vram_peak&quot;] = int(torch.cuda.max_memory_allocated()) if cuda else 0\n    record[&quot;videos&quot;] = videos\n    for vid, raw in blobs.items():\n        for index in range(0, len(raw), CHUNK_BYTES):\n            yield {&quot;kind&quot;: &quot;chunk&quot;, &quot;id&quot;: vid, &quot;index&quot;: index \/\/ CHUNK_BYTES, &quot;data&quot;: raw[index:index + CHUNK_BYTES]}\n    yield {&quot;kind&quot;: &quot;record&quot;, **plain(record)}\n\ndef plain(value):\n    &quot;&quot;&quot;JSON \u306b\u901a\u3057\u3066\u3001\u6a19\u6e96\u306e\u578b\u3060\u3051\u306b\u3059\u308b(\u30db\u30b9\u30c8\u306b\u306f torch \u3082 diffusers \u3082\u7121\u3044)\u3002&quot;&quot;&quot;\n    return json.loads(json.dumps(value, default=str))\n<\/code><\/pre>\n<p>The <code>job<\/code> passed to <code>download<\/code> (as used):<\/p>\n<pre><code class=\"language-json\">{\n  &quot;dir&quot;: &quot;video-1790914468&quot;,\n  &quot;base&quot;: {\n    &quot;repo&quot;: &quot;Wan-AI\/Wan2.1-T2V-14B-Diffusers&quot;,\n    &quot;revision&quot;: &quot;38ec498cb3208fb688890f8cc7e94ede2cbd7f68&quot;,\n    &quot;files&quot;: [\n      &quot;model_index.json&quot;,\n      &quot;scheduler\/scheduler_config.json&quot;,\n      &quot;text_encoder\/config.json&quot;,\n      &quot;text_encoder\/model-00001-of-00005.safetensors&quot;,\n      &quot;text_encoder\/model-00002-of-00005.safetensors&quot;,\n      &quot;text_encoder\/model-00003-of-00005.safetensors&quot;,\n      &quot;text_encoder\/model-00004-of-00005.safetensors&quot;,\n      &quot;text_encoder\/model-00005-of-00005.safetensors&quot;,\n      &quot;text_encoder\/model.safetensors.index.json&quot;,\n      &quot;tokenizer\/special_tokens_map.json&quot;,\n      &quot;tokenizer\/spiece.model&quot;,\n      &quot;tokenizer\/tokenizer.json&quot;,\n      &quot;tokenizer\/tokenizer_config.json&quot;,\n      &quot;transformer\/config.json&quot;,\n      &quot;transformer\/diffusion_pytorch_model-00001-of-00012.safetensors&quot;,\n      &quot;transformer\/diffusion_pytorch_model-00002-of-00012.safetensors&quot;,\n      &quot;transformer\/diffusion_pytorch_model-00003-of-00012.safetensors&quot;,\n      &quot;transformer\/diffusion_pytorch_model-00004-of-00012.safetensors&quot;,\n      &quot;transformer\/diffusion_pytorch_model-00005-of-00012.safetensors&quot;,\n      &quot;transformer\/diffusion_pytorch_model-00006-of-00012.safetensors&quot;,\n      &quot;transformer\/diffusion_pytorch_model-00007-of-00012.safetensors&quot;,\n      &quot;transformer\/diffusion_pytorch_model-00008-of-00012.safetensors&quot;,\n      &quot;transformer\/diffusion_pytorch_model-00009-of-00012.safetensors&quot;,\n      &quot;transformer\/diffusion_pytorch_model-00010-of-00012.safetensors&quot;,\n      &quot;transformer\/diffusion_pytorch_model-00011-of-00012.safetensors&quot;,\n      &quot;transformer\/diffusion_pytorch_model-00012-of-00012.safetensors&quot;,\n      &quot;transformer\/diffusion_pytorch_model.safetensors.index.json&quot;,\n      &quot;vae\/config.json&quot;,\n      &quot;vae\/diffusion_pytorch_model.safetensors&quot;\n    ]\n  },\n  &quot;loras&quot;: [\n    {\n      &quot;repo&quot;: &quot;Efficient-Large-Model\/LongLive-Plug-Wan2.1-T2V-14B-few-step&quot;,\n      &quot;revision&quot;: &quot;f125af0533b94e2cee0163a7a42bb736d59a1d37&quot;,\n      &quot;file&quot;: &quot;generator_lora_lightx2v.safetensors&quot;\n    },\n    {\n      &quot;repo&quot;: &quot;Efficient-Large-Model\/LongLive-Plug-Wan2.1-T2V-14B-cfg&quot;,\n      &quot;revision&quot;: &quot;32b8aa3d1db3d178a9c82f3731cc917a34fb7693&quot;,\n      &quot;file&quot;: &quot;adapter_model.safetensors&quot;\n    }\n  ]\n}\n<\/code><\/pre>\n<p>The <code>job<\/code> passed to <code>run<\/code> (as used):<\/p>\n<pre><code class=\"language-json\">{\n  &quot;dir&quot;: &quot;video-1790914468&quot;,\n  &quot;pipeline&quot;: &quot;WanPipeline&quot;,\n  &quot;settings&quot;: {\n    &quot;height&quot;: 480,\n    &quot;width&quot;: 832,\n    &quot;num_frames&quot;: 81,\n    &quot;fps&quot;: 16,\n    &quot;steps&quot;: 4,\n    &quot;guidance&quot;: 1.0,\n    &quot;flow_shift&quot;: 5.0\n  },\n  &quot;seed&quot;: 0,\n  &quot;prompts&quot;: [\n    {\n      &quot;id&quot;: &quot;boat&quot;,\n      &quot;en&quot;: &quot;a small red paper boat drifting down a clear forest stream, sunlight flickering through the leaves, gentle ripples, realistic&quot;\n    },\n    {\n      &quot;id&quot;: &quot;clouds&quot;,\n      &quot;en&quot;: &quot;time-lapse of white clouds rolling over snowy mountain peaks at sunrise, golden light, wide shot&quot;\n    }\n  ],\n  &quot;loras&quot;: [\n    {\n      &quot;file&quot;: &quot;generator_lora_lightx2v.safetensors&quot;,\n      &quot;weight&quot;: 1.0,\n      &quot;alpha&quot;: 128,\n      &quot;rank&quot;: 128\n    },\n    {\n      &quot;file&quot;: &quot;adapter_model.safetensors&quot;,\n      &quot;weight&quot;: 0.5,\n      &quot;alpha&quot;: 128,\n      &quot;rank&quot;: 128\n    }\n  ],\n  &quot;compare_base&quot;: true,\n  &quot;max_bytes&quot;: 12000000\n}\n<\/code><\/pre>\n<details>\n<summary>Package versions in the generating container (full list)<\/summary>\n<pre><code>accelerate==1.15.0 aiohappyeyeballs==2.6.1 aiohttp==3.12.7 aiosignal==1.3.2 annotated-doc==0.0.5 anyio==4.15.1 attrs==25.3.0 cbor2==5.7.0 certifi==2026.7.22 charset-normalizer==3.5.2 click==8.5.0 cuda-bindings==13.4.3 cuda-pathfinder==1.8.2 cuda-toolkit==13.0.3.0 diffusers==0.40.0 filelock==4.0.9 frozenlist==1.6.0 fsspec==2026.9.0 ftfy==6.3.1 grpclib==0.4.8 h11==0.16.0 h2==4.2.0 hf-xet==1.6.0 hpack==4.1.0 httpcore==1.0.9 httpx==0.28.1 huggingface_hub==1.33.0 hyperframe==6.1.0 idna==3.20 imageio-ffmpeg==0.6.0 importlib_metadata==9.0.1 Jinja2==3.1.6 markdown-it-py==4.2.0 MarkupSafe==3.0.3 mdurl==0.1.2 mpmath==1.3.0 multidict==6.4.4 networkx==3.7 numpy==2.5.3 nvidia-cublas==13.1.1.3 nvidia-cuda-cupti==13.0.85 nvidia-cuda-nvrtc==13.0.88 nvidia-cuda-runtime==13.0.96 nvidia-cudnn-cu13==9.24.0.43 nvidia-cufft==12.0.0.61 nvidia-cufile==1.15.1.6 nvidia-curand==10.4.0.35 nvidia-cusolver==12.0.4.66 nvidia-cusparse==12.6.3.3 nvidia-cusparselt-cu13==0.8.1 nvidia-nccl-cu13==2.30.7 nvidia-nvjitlink==13.4.92 nvidia-nvshmem-cu13==3.4.5 nvidia-nvtx==13.0.85 packaging==26.3 pillow==12.3.0 pip==25.1.1 propcache==0.3.1 protobuf==6.31.1 psutil==7.2.2 Pygments==2.21.0 PyYAML==6.0.3 regex==2026.9.29 requests==2.34.2 rich==15.0.0 safetensors==0.8.0 sentencepiece==0.2.2 setuptools==84.0.0 shellingham==1.5.4 sympy==1.14.0 tokenizers==0.23.2 torch==2.14.1 tqdm==4.70.1 transformers==5.18.0 triton==3.8.0 typer==0.27.2 typing_extensions==4.16.0 urllib3==2.8.0 uv==0.7.19 wcwidth==0.9.1 wheel==0.45.1 yarl==1.20.0 zipp==4.1.0<\/code><\/pre>\n<\/details>\n<details>\n<summary>Package versions in the downloading container (full list)<\/summary>\n<pre><code>aiohappyeyeballs==2.6.1 aiohttp==3.12.7 aiosignal==1.3.2 anyio==4.15.1 attrs==25.3.0 cbor2==5.7.0 certifi==2025.4.26 click==8.5.0 filelock==4.0.7 frozenlist==1.6.0 fsspec==2026.9.0 grpclib==0.4.8 h11==0.16.0 h2==4.2.0 hf-xet==1.6.0 hpack==4.1.0 httpcore2==2.13.1 httpx2==2.13.1 huggingface_hub==2.0.0 hyperframe==6.1.0 idna==3.20 multidict==6.4.4 packaging==26.3 pip==25.1.1 propcache==0.3.1 protobuf==6.31.1 PyYAML==6.0.3 tqdm==4.70.1 truststore==0.10.4 typing_extensions==4.16.0 uv==0.7.19 wheel==0.45.1 yarl==1.20.0<\/code><\/pre>\n<\/details>\n<p><!-- \/lmw:lab --><\/p>\n<p><!-- lmw:related --><\/p>\n<h2>Related Articles<\/h2>\n<ul>\n<li><a href=\"https:\/\/localmodelwatch.tsuchitsuchi.com\/en\/2026\/09\/30\/longlive-plug-wan21-t2v-14b-few-step-2\/\">LongLive-Plug-Wan2.1-T2V-14B-few-step: Our Generated Video, File List<\/a><\/li>\n<li><a href=\"https:\/\/localmodelwatch.tsuchitsuchi.com\/en\/2026\/09\/29\/longlive-plug-wan21-ti2v-5b-cfg-lora\/\">LongLive-Plug-Wan2.2-TI2V-5B-cfg: Our Generated Video, File List<\/a><\/li>\n<li><a href=\"https:\/\/localmodelwatch.tsuchitsuchi.com\/en\/2026\/09\/29\/longlive-plug-wan2-2-ti2v-5b-few-step-2\/\">LongLive-Plug-Wan2.2-TI2V-5B-few-step: Our Generated Video, File List<\/a><\/li>\n<li><a href=\"https:\/\/localmodelwatch.tsuchitsuchi.com\/en\/2026\/09\/10\/h3-to-ltx-latent-adapter-released\/\">H3-to-LTX-Latent-Adapter: 4GB+ VRAM, File List<\/a><\/li>\n<\/ul>\n<p><!-- \/lmw:related --><\/p>\n<p><!-- lmw:next-steps --><\/p>\n<h2>What to Read Next<\/h2>\n<ul>\n<li><strong>Formats this model is available in<\/strong> \u2192 <a href=\"https:\/\/localmodelwatch.tsuchitsuchi.com\/en\/format-safetensors-en\/\">Safetensors format guide and models<\/a><\/li>\n<li><strong>Learn about the publisher<\/strong> \u2192 <a href=\"https:\/\/localmodelwatch.tsuchitsuchi.com\/en\/publisher-efficient-large-model-en\/\">Efficient Large Model (NVIDIA and MIT): models, licenses and articles<\/a><\/li>\n<li><strong>Other models for the same task<\/strong> \u2192 <a href=\"https:\/\/localmodelwatch.tsuchitsuchi.com\/en\/models-by-task-en\/#task-video\">Other video generation models<\/a><\/li>\n<\/ul>\n<p><!-- \/lmw:next-steps --><\/p>\n<h2>Sources<\/h2>\n<ul>\n<li><a href=\"https:\/\/huggingface.co\/Efficient-Large-Model\/LongLive-Plug-Wan2.1-T2V-14B-cfg\">https:\/\/huggingface.co\/Efficient-Large-Model\/LongLive-Plug-Wan2.1-T2V-14B-cfg<\/a><\/li>\n<\/ul>\n<p><!-- lmw:updates --><\/p>\n<h2>Update History<\/h2>\n<ul>\n<li>2026-09-30: Changed the title to show what the article covers (VRAM requirements, file list, etc.).<\/li>\n<li>2026-10-02: Added our own measurements: video we generated.<\/li>\n<li>2026-10-02: Changed the title to show what the article covers (VRAM requirements, file list, etc.).<\/li>\n<\/ul>\n<p><!-- \/lmw:updates --><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Learn about LongLive-Plug-Wan2.1-T2V-14B-cfg, a LoRA adapter for Wan2.1-T2V-14B designed to distill Classifier-Free Guidance.<\/p>\n","protected":false},"author":1,"featured_media":9124,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[203],"tags":[1833,724,111,1547,2675,2677,2679,959],"class_list":["post-7404","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-image-video-and-audio","tag-dit-en","tag-efficient-large-model-en","tag-lora-en","tag-verified","tag-video-diffusion-en","tag-wan2-1-en","tag-wan2-1-t2v-en","tag--en"],"lang":"en","translations":{"en":7404,"ja":7402},"_links":{"self":[{"href":"https:\/\/localmodelwatch.tsuchitsuchi.com\/en\/wp-json\/wp\/v2\/posts\/7404","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/localmodelwatch.tsuchitsuchi.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/localmodelwatch.tsuchitsuchi.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/localmodelwatch.tsuchitsuchi.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/localmodelwatch.tsuchitsuchi.com\/en\/wp-json\/wp\/v2\/comments?post=7404"}],"version-history":[{"count":12,"href":"https:\/\/localmodelwatch.tsuchitsuchi.com\/en\/wp-json\/wp\/v2\/posts\/7404\/revisions"}],"predecessor-version":[{"id":9173,"href":"https:\/\/localmodelwatch.tsuchitsuchi.com\/en\/wp-json\/wp\/v2\/posts\/7404\/revisions\/9173"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/localmodelwatch.tsuchitsuchi.com\/en\/wp-json\/wp\/v2\/media\/9124"}],"wp:attachment":[{"href":"https:\/\/localmodelwatch.tsuchitsuchi.com\/en\/wp-json\/wp\/v2\/media?parent=7404"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/localmodelwatch.tsuchitsuchi.com\/en\/wp-json\/wp\/v2\/categories?post=7404"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/localmodelwatch.tsuchitsuchi.com\/en\/wp-json\/wp\/v2\/tags?post=7404"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}