Buckets:
| <meta charset="utf-8" /><meta name="hf:doc:metadata" content="{"title":"Song song tensor","local":"tensor-parallelism","sections":[{"title":"Tải một mô hình phân mảnh","local":"load-a-sharded-model","sections":[],"depth":2},{"title":"Hiệu năng tải","local":"loading-performance","sections":[],"depth":2},{"title":"Hạn chế","local":"limitations","sections":[],"depth":2},{"title":"Thêm song song tensor vào một mô hình","local":"add-tensor-parallelism-to-a-model","sections":[{"title":"Colwise và rowwise","local":"colwise-and-rowwise","sections":[],"depth":3},{"title":"Các phép chiếu đã hợp nhất","local":"fused-projections","sections":[],"depth":3},{"title":"Những gì cần loại bỏ","local":"what-to-leave-out","sections":[],"depth":3},{"title":"Ràng buộc và xác minh","local":"constraints-and-verification","sections":[],"depth":3}],"depth":2}],"depth":1}"/> | |
| <link href="/docs/diffusers/main/en/_app/immutable/entry/start.0S0_iEoG.js" rel="modulepreload"> | |
| <link href="/docs/diffusers/main/en/_app/immutable/chunks/I9eooN77.js" rel="modulepreload"> | |
| <link href="/docs/diffusers/main/en/_app/immutable/chunks/Bupkjr9f.js" rel="modulepreload"> | |
| <link href="/docs/diffusers/main/en/_app/immutable/entry/app.CPdOxCbw.js" rel="modulepreload"> | |
| <link href="/docs/diffusers/main/en/_app/immutable/chunks/CyvZ3FS5.js" rel="modulepreload"> | |
| <link href="/docs/diffusers/main/en/_app/immutable/chunks/l0QnnOED.js" rel="modulepreload"> | |
| <link href="/docs/diffusers/main/en/_app/immutable/chunks/DnVIJfC5.js" rel="modulepreload"> | |
| <link href="/docs/diffusers/main/en/_app/immutable/chunks/DsnmJJEf.js" rel="modulepreload"> | |
| <link href="/docs/diffusers/main/en/_app/immutable/nodes/0.DteTvmQZ.js" rel="modulepreload"> | |
| <link href="/docs/diffusers/main/en/_app/immutable/chunks/CoSrdQax.js" rel="modulepreload"> | |
| <link href="/docs/diffusers/main/en/_app/immutable/nodes/347.DnqzUbRP.js" rel="modulepreload"> | |
| <link href="/docs/diffusers/main/en/_app/immutable/chunks/DSPDl1gz.js" rel="modulepreload"> | |
| <!--17gkrup--><meta name="hf:doc:metadata" content="{"title":"Tensor parallelism","local":"tensor-parallelism","sections":[{"title":"Load a sharded model","local":"load-a-sharded-model","sections":[],"depth":2},{"title":"Loading performance","local":"loading-performance","sections":[],"depth":2},{"title":"Limitations","local":"limitations","sections":[],"depth":2},{"title":"Add tensor parallelism to a model","local":"add-tensor-parallelism-to-a-model","sections":[{"title":"Colwise and rowwise","local":"colwise-and-rowwise","sections":[],"depth":3},{"title":"Fused projections","local":"fused-projections","sections":[],"depth":3},{"title":"What to leave out","local":"what-to-leave-out","sections":[],"depth":3},{"title":"Constraints and verification","local":"constraints-and-verification","sections":[],"depth":3}],"depth":2}],"depth":1}"/><!----> | |
| <link href="/docs/diffusers/main/en/_app/immutable/assets/0.tn0RQdqM.css" rel="modulepreload"> <!--[--><!--[0--><!--[--><!--[0--><!--[--><p></p> <div class="items-center shrink-0 min-w-[100px] max-sm:min-w-[50px] justify-end ml-auto flex" style="float: inline-end; margin-inline-start: 10px; display: inline-flex; position: relative; z-index: 10;"><div dir="ltr" class="inline-flex rounded-md max-sm:rounded-sm"><button class="inline-flex items-center gap-1 h-7 max-sm:h-7 px-2 max-sm:px-1.5 text-sm font-medium text-gray-800 border border-r-0 rounded-l-md max-sm:rounded-l-sm border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-live="polite"><span class="inline-flex items-center justify-center rounded-md p-0.5 max-sm:p-0 hover:text-gray-800 dark:hover:text-gray-200"><svg class="sm:size-3.5 size-3" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----></span> <span dir="auto">Copy page</span></button> <button class="inline-flex items-center justify-center w-6 max-sm:w-5 h-7 max-sm:h-7 disabled:pointer-events-none text-sm text-gray-500 hover:text-gray-700 dark:hover:text-white rounded-r-md max-sm:rounded-r-sm border border-l transition border-gray-200 bg-white hover:shadow-inner dark:border-gray-850 dark:bg-gray-950 dark:text-gray-200 dark:hover:bg-gray-800" aria-haspopup="menu" aria-expanded="false" aria-label="Open copy menu"><svg class="transition-transform text-gray-400 overflow-visible sm:size-3.5 size-3 rotate-0" width="1em" height="1em" viewBox="0 0 12 7" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M1 1L6 6L11 1" stroke="currentColor"></path></svg><!----></button></div> <!--[-1--><!--]--></div><!----> <!--[0--><h1 class="relative group"><a id="tensor-parallelism" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#tensor-parallelism"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span><!---->Song song tensor<!----></span></h1><!--]--><!----> <p><a href="https://huggingface.co/spaces/nanotron/ultrascale-playbook?section=tensor_parallelism" rel="nofollow">Tensor parallelism</a> chia nhỏ các ma trận trọng số của mô hình trên các thiết bị. Mỗi thiết bị giữ một lát cắt theo cột (<code>"colwise"</code>) hoặc theo hàng (<code>"rowwise"</code>) của mỗi lớp và tính toán một kết quả cục bộ. Một <code>AllReduce</code> hoặc <code>AllGather</code> tại ranh giới lớp sẽ kết hợp các kết quả cục bộ thành đầu ra đầy đủ. Khác với <a href="./context_parallelism">context parallelism</a>, nó giảm bộ nhớ <em>weight</em> trên mỗi thiết bị, hữu ích khi mô hình không vừa trên một thiết bị. Xem <a href="../training/distributed_inference">Distributed inference</a> để so sánh với các chiến lược khác.</p> <!--[1--><h2 class="relative group"><a id="load-a-sharded-model" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#load-a-sharded-model"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span><!---->Tải một mô hình phân mảnh<!----></span></h2><!--]--><!----> <p>Truyền một <a href="/docs/diffusers/main/vi/api/parallel#diffusers.TensorParallelConfig">TensorParallelConfig</a> vào tham số <code>parallel_config</code> của <a href="/docs/diffusers/main/vi/api/models/overview#diffusers.ModelMixin.from_pretrained">from_pretrained()</a> của mô hình. <code>tp_degree</code> là số lượng thiết bị để chia nhỏ và phải chia hết cho số lượng đầu chú ý của mô hình. Lớp của mô hình phải định nghĩa <code>_tp_plan</code>, ánh xạ tên module sang kiểu chia nhỏ. Để kiểm tra xem một mô hình có hỗ trợ song song tensor hay không, hãy tìm thuộc tính này trên lớp của nó, chẳng hạn như <a href="/docs/diffusers/main/vi/api/models/flux2_transformer#diffusers.Flux2Transformer2DModel">Flux2Transformer2DModel</a>.</p> <p>Để thêm một kế hoạch vào một mô hình khác, hãy xem <a href="#add-tensor-parallelism-to-a-model">Thêm song song tensor vào một mô hình</a>.</p> <p>Việc nạp theo cách này sẽ chia checkpoint thành các mảnh khi đọc. Mỗi rank chỉ đọc phần riêng của mình trong mỗi trọng số và đặt trực tiếp lên GPU của nó, do đó không rank nào giữ toàn bộ trọng số ở kích thước đầy đủ. Bộ nhớ trên mỗi rank giảm khi <code>tp_degree</code> tăng.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----> <div class=" absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0 "><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent;"></div> Đã sao chép</div><!----></button><!----></div> <pre class="language-py "><!----><span class="hljs-keyword">import</span> os | |
| <span class="hljs-keyword">import</span> torch | |
| <span class="hljs-keyword">from</span> torch <span class="hljs-keyword">import</span> distributed <span class="hljs-keyword">as</span> dist | |
| <span class="hljs-keyword">from</span> diffusers <span class="hljs-keyword">import</span> DiffusionPipeline, Flux2Transformer2DModel, TensorParallelConfig | |
| <span class="hljs-keyword">def</span> <span class="hljs-title function_">main</span>(): | |
| dist.init_process_group(backend=<span class="hljs-string">"nccl"</span>) | |
| rank, world_size = dist.get_rank(), dist.get_world_size() | |
| <span class="hljs-comment"># torchrun sets LOCAL_RANK to this process's GPU index on its node</span> | |
| local_rank = <span class="hljs-built_in">int</span>(os.environ[<span class="hljs-string">"LOCAL_RANK"</span>]) | |
| device = torch.device(<span class="hljs-string">f"cuda:<span class="hljs-subst">{local_rank}</span>"</span>) | |
| torch.cuda.set_device(device) | |
| <span class="hljs-comment"># Each rank reads only its own shard of every planned weight, straight onto its own GPU.</span> | |
| transformer = Flux2Transformer2DModel.from_pretrained( | |
| <span class="hljs-string">"black-forest-labs/FLUX.2-dev"</span>, | |
| subfolder=<span class="hljs-string">"transformer"</span>, | |
| dtype=torch.bfloat16, | |
| parallel_config=TensorParallelConfig(tp_degree=world_size), | |
| ) | |
| pipeline = DiffusionPipeline.from_pretrained( | |
| <span class="hljs-string">"black-forest-labs/FLUX.2-dev"</span>, transformer=transformer, dtype=torch.bfloat16 | |
| ) | |
| <span class="hljs-comment"># The transformer is already on its device; move the remaining components individually. Do not call</span> | |
| <span class="hljs-comment"># `pipeline.to(device)` — that would move every rank's shards onto the same device.</span> | |
| pipeline.text_encoder.to(device) | |
| pipeline.vae.to(device) | |
| generator = torch.Generator().manual_seed(<span class="hljs-number">42</span>) | |
| image = pipeline(prompt=<span class="hljs-string">"a cat holding a sign that says hello"</span>, generator=generator).images[<span class="hljs-number">0</span>] | |
| <span class="hljs-keyword">if</span> rank == <span class="hljs-number">0</span>: | |
| image.save(<span class="hljs-string">"output.png"</span>) | |
| dist.destroy_process_group() | |
| <span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>: | |
| main()<!----></pre></div><!----> <p>Lưu script dưới tên <code>tensor_parallel_flux2.py</code> và chạy nó bằng <code>torchrun</code>.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----> <div class=" absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0 "><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent;"></div> Đã sao chép</div><!----></button><!----></div> <pre class="language-shell "><!---->torchrun --nproc-per-node 4 tensor_parallel_flux2.py<!----></pre></div><!----> <p>Script đặt <code>tp_degree</code> bằng <code>world_size</code>, do đó <code>--nproc-per-node 4</code> sẽ chia transformer thành 4 phần trên 4 GPU.</p> <p>Chỉ có transformer được chia nhỏ. Mỗi rank giữ một bản sao đầy đủ của text encoder, do đó mỗi GPU cần đủ bộ nhớ cho text encoder cùng với phần transformer của nó.</p> <!--[1--><h2 class="relative group"><a id="loading-performance" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#loading-performance"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span><!---->Hiệu năng tải<!----></span></h2><!--]--><!----> <p>Việc nạp với <code>parallel_config</code> nhanh hơn và sử dụng ít bộ nhớ CPU hơn trên mỗi rank so với việc nạp toàn bộ mô hình rồi gọi <code>enable_parallelism()</code>. Bảng dưới đây cho thấy kết quả với <a href="https://huggingface.co/black-forest-labs/FLUX.2-dev" rel="nofollow">black-forest-labs/FLUX.2-dev</a> (chỉ transformer, 32B tham số, bf16) trên 4x A10G (23GB).</p> <table><thead><tr><th>tp_degree</th><th>phương thức</th><th>thời gian tải</th><th>CPU tối đa/mỗi rank</th></tr></thead><tbody><tr><td>4</td><td><code>from_pretrained(parallel_config=...)</code></td><td>12.5s</td><td>6.8GB</td></tr><tr><td>4</td><td><code>from_pretrained</code> + <code>enable_parallelism</code></td><td>30.4s</td><td>64.1GB</td></tr></tbody></table> <!--[1--><h2 class="relative group"><a id="limitations" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#limitations"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span><!---->Hạn chế<!----></span></h2><!--]--><!----> <p>Tensor parallelism không hoạt động với một số tùy chọn và tính năng tải, và bạn không thể lưu một mô hình đã được chia mảnh.</p> <ul><li>Việc tải với <code>parallel_config</code> tensor-parallel không hoạt động cùng với <code>device_map</code>, <code>quantization_config</code>, <code>low_cpu_mem_usage=False</code>, <code>use_flashpack=True</code>, hoặc trọng lượng không phải safetensors. Mỗi trường hợp sẽ gây ra lỗi thay vì âm thầm tải toàn bộ checkpoint.</li> <li>Việc kết hợp tensor parallelism với quantization, offloading hoặc các adapter LoRA cũng sẽ gây ra lỗi, bất kể mô hình được sharded theo cách nào.</li> <li>Để chia nhỏ (shard) một model đã nằm trong bộ nhớ, hãy gọi <code>enable_parallelism()</code> với cùng một config. Hàm này sẽ tải toàn bộ model trước rồi mới chia nhỏ, do đó mỗi rank cần bộ nhớ cho toàn bộ checkpoint. Việc tải bằng <code>parallel_config</code> giúp tránh chi phí đó.</li> <li>Việc lưu một mô hình song song tensor sẽ gây ra lỗi trong <a href="/docs/diffusers/main/vi/api/models/overview#diffusers.ModelMixin.save_pretrained">save_pretrained()</a>. Hãy lưu mô hình trước khi chia nhỏ (sharding) nó.</li></ul> <!--[1--><h2 class="relative group"><a id="add-tensor-parallelism-to-a-model" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#add-tensor-parallelism-to-a-model"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span><!---->Thêm song song tensor vào một mô hình<!----></span></h2><!--]--><!----> <p>Phần này dành cho những người đóng góp muốn thêm hỗ trợ song song tensor cho một mô hình Diffusers.</p> <p>Tensor parallelism chỉ hoạt động trên các model có định nghĩa <code>_tp_plan</code>, một thuộc tính lớp ánh xạ tên module sang kiểu sharding. Việc viết một <code>_tp_plan</code> chủ yếu là ghép mỗi projection <em>mở rộng</em> chiều hidden với projection <em>thu gọn</em> nó lại.</p> <p>Mỗi key có thể chứa tối đa một <code>*</code>, và phần trước <code>*</code> phải trỏ đến một <a href="https://pytorch.org/docs/stable/generated/torch.nn.ModuleList.html" rel="nofollow"><code>nn.ModuleList</code></a>, do đó một entry sẽ bao phủ mọi block. Key không có <code>*</code> sẽ áp dụng cho chính model. Các đường dẫn là tương đối so với model.</p> <!--[2--><h3 class="relative group"><a id="colwise-and-rowwise" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#colwise-and-rowwise"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span><!---->Colwise và rowwise<!----></span></h3><!--]--><!----> <table><thead><tr><th>Phong cách</th><th>Các phân mảnh</th><th>Mỗi rank</th><th>Dùng cho</th></tr></thead><tbody><tr><td><code>"colwise"</code></td><td>đặc trưng đầu ra (<code>weight</code> chiều 0)</td><td>tính toán một lát cắt của đầu ra</td><td><code>to_q</code>, <code>to_k</code>, <code>to_v</code>, FFN in-projection</td></tr><tr><td><code>"rowwise"</code></td><td>đặc trưng đầu vào (chiều 1 của <code>weight</code>)</td><td>tính tổng một phần</td><td><code>to_out.0</code>, chiếu ra đầu ra của FFN</td></tr><tr><td><code>"rowwise_split_input"</code></td><td>đặc trưng đầu vào (chiều 1 của <code>weight</code>)</td><td>tính tổng một phần từ lát cắt của đầu vào được nhân bản</td><td>một phép chiếu độc lập có đầu vào được nhân bản, chẳng hạn như phép chiếu điều biến AdaLN đọc nhúng bước thời gian</td></tr></tbody></table> <p>Luôn ghép <code>"colwise"</code> và <code>"rowwise"</code> theo đúng thứ tự đó. Một phép chiếu <code>"colwise"</code> để đầu ra của nó ở dạng sharded, phép chiếu <code>"rowwise"</code> tiếp theo tiêu thụ shard đó trực tiếp, và một <code>AllReduce</code> duy nhất tại ranh giới khối tái tạo kết quả. Việc chia shard cặp này theo bất kỳ cách nào khác sẽ buộc phải thực hiện gather ở giữa và truyền thông nhiều hơn rất nhiều.</p> <p>Trong cơ chế chú ý, các phép chiếu Q, K và V theo cột cấp cho mỗi rank một tập con các đầu, do đó <code>tp_degree</code> phải chia hết cho số lượng đầu. Các bản sao của luồng encoder (<code>add_q_proj</code>, <code>to_add_out</code>, <code>ff_context</code>) tuân theo cùng một mẫu như các phần tử tương ứng của luồng ảnh.</p> <!--[2--><h3 class="relative group"><a id="fused-projections" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#fused-projections"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span><!---->Các phép chiếu đã hợp nhất<!----></span></h3><!--]--><!----> <p>Khi một <code>Linear</code> đóng gói nhiều tensor logic dọc theo chiều đang được chia nhỏ, việc cắt đơn giản theo <code>"colwise"</code>/<code>"rowwise"</code> xuyên qua phần ghép nối sẽ làm lệch các mảnh. Hãy dùng <code>PackedColwiseParallel</code>/<code>PackedRowwiseParallel</code> thay vào đó, vì chúng chia nhỏ từng khối đã đóng gói một cách độc lập.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----> <div class=" absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0 "><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent;"></div> Đã sao chép</div><!----></button><!----></div> <pre class="language-py "><!----><span class="hljs-comment"># in src/diffusers/models/transformers/your_model.py</span> | |
| <span class="hljs-keyword">from</span> ...hooks.tensor_parallel <span class="hljs-keyword">import</span> PackedColwiseParallel, PackedRowwiseParallel<!----></pre></div><!----> <p>Truyền <code>blocks</code>, một danh sách các số nguyên tỷ lệ có tổng chia hết cho chiều đã đóng gói. Ví dụ, sử dụng <code>[1, 1]</code> cho phép và phép chiếu lên của SwiGLU có hai nửa bằng nhau, hoặc <code>[1, 1, 1, 3, 3]</code> cho phép chiếu Q, K, V, gate và up đã hợp nhất với <code>mlp_ratio=3</code>.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----> <div class=" absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0 "><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent;"></div> Đã sao chép</div><!----></button><!----></div> <pre class="language-py "><!----><span class="hljs-string">"transformer_blocks.*.ff.linear_in"</span>: PackedColwiseParallel([<span class="hljs-number">1</span>, <span class="hljs-number">1</span>]),<!----></pre></div><!----> <p>Khi kích thước khối chỉ được biết từ cấu hình, hãy bỏ qua <code>blocks</code> và thay vào đó lưu các kích thước tuyệt đối trên <code>Linear</code> trong <code>__init__</code> dưới dạng <code>_tp_packed_col_blocks</code> hoặc <code>_tp_packed_row_blocks</code>.</p> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----> <div class=" absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0 "><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent;"></div> Đã sao chép</div><!----></button><!----></div> <pre class="language-py "><!----><span class="hljs-comment"># in the attention module's __init__</span> | |
| <span class="hljs-variable language_">self</span>.to_out._tp_packed_row_blocks = [<span class="hljs-variable language_">self</span>.inner_dim, <span class="hljs-variable language_">self</span>.mlp_hidden_dim]<!----></pre></div><!----> <div class="code-block relative "><div class="absolute top-2.5 right-4"><button class="inline-flex items-center relative text-sm focus:text-green-500 cursor-pointer focus:outline-none transition duration-200 ease-in-out opacity-0 mx-0.5 text-gray-600 " title="code excerpt" type="button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M28,10V28H10V10H28m0-2H10a2,2,0,0,0-2,2V28a2,2,0,0,0,2,2H28a2,2,0,0,0,2-2V10a2,2,0,0,0-2-2Z" transform="translate(0)"></path><path d="M4,18H2V4A2,2,0,0,1,4,2H18V4H4Z" transform="translate(0)"></path><rect fill="none" width="32" height="32"></rect></svg><!----> <div class=" absolute pointer-events-none transition-opacity bg-black text-white py-1 px-2 leading-tight rounded font-normal shadow left-1/2 top-full transform -translate-x-1/2 translate-y-2 opacity-0 "><div class="absolute bottom-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-black border-4 border-t-0" style="border-left-color: transparent; border-right-color: transparent;"></div> Đã sao chép</div><!----></button><!----></div> <pre class="language-py "><!----><span class="hljs-comment"># in the model's _tp_plan</span> | |
| <span class="hljs-string">"single_transformer_blocks.*.attn.to_out"</span>: PackedRowwiseParallel(),<!----></pre></div><!----> <p>Kế hoạch trong <a href="https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/transformers/transformer_flux2.py" rel="nofollow"><code>transformer_flux2.py</code></a> sử dụng cả hai dạng. Cặp SwiGLU double-stream truyền <code>blocks</code> trực tiếp. Dự toán QKV và MLP single-stream đã hợp nhất lưu kích thước của chúng trên <code>Linear</code> trong <code>Flux2ParallelSelfAttention.__init__</code>, vì chúng phụ thuộc vào <code>mlp_ratio</code> và <code>mlp_mult_factor</code>.</p> <!--[2--><h3 class="relative group"><a id="what-to-leave-out" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#what-to-leave-out"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span><!---->Những gì cần loại bỏ<!----></span></h3><!--]--><!----> <p>Các module không được đưa vào kế hoạch sẽ được nhân bản trên mọi rank. Hãy bỏ qua các lớp chuẩn hóa, embedding patch và text, cùng với <code>norm_out</code> và <code>proj_out</code> cuối cùng. Chúng nhỏ, nên việc chia nhỏ chúng chỉ tiết kiệm được ít bộ nhớ mà lại làm tăng giao tiếp. Điều chế AdaLN (<code>img_mod</code> và <code>txt_mod</code>) thường đủ nhỏ để cũng có thể bỏ qua. Khi nó lớn, như <code>adaln_proj.linear</code> của MiniMax-H3, hãy chia nhỏ nó bằng <code>"rowwise_split_input"</code>.</p> <!--[2--><h3 class="relative group"><a id="constraints-and-verification" class="header-link block pr-1.5 text-lg no-hover:hidden with-hover:absolute with-hover:p-1.5 with-hover:opacity-0 with-hover:group-hover:opacity-100 with-hover:right-full" href="#constraints-and-verification"><span><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 256"><path d="M167.594 88.393a8.001 8.001 0 0 1 0 11.314l-67.882 67.882a8 8 0 1 1-11.314-11.315l67.882-67.881a8.003 8.003 0 0 1 11.314 0zm-28.287 84.86l-28.284 28.284a40 40 0 0 1-56.567-56.567l28.284-28.284a8 8 0 0 0-11.315-11.315l-28.284 28.284a56 56 0 0 0 79.196 79.197l28.285-28.285a8 8 0 1 0-11.315-11.314zM212.852 43.14a56.002 56.002 0 0 0-79.196 0l-28.284 28.284a8 8 0 1 0 11.314 11.314l28.284-28.284a40 40 0 0 1 56.568 56.567l-28.285 28.285a8 8 0 0 0 11.315 11.314l28.284-28.284a56.065 56.065 0 0 0 0-79.196z" fill="currentColor"></path></svg><!----></span></a> <span><!---->Ràng buộc và xác minh<!----></span></h3><!--]--><!----> <ul><li><code>tp_degree</code> phải chia hết cho <code>config.num_attention_heads</code>.</li> <li>Mỗi khối được đóng gói phải <em>riêng lẻ</em> chia hết cho <code>tp_degree</code>, không chỉ tổng của chúng.</li></ul> <p><a href="/docs/diffusers/main/vi/api/models/overview#diffusers.ModelMixin.from_pretrained">from_pretrained()</a> và <code>enable_parallelism()</code> kiểm tra cả hai trước khi tải hoặc chia nhỏ bất kỳ trọng số nào.</p> <p>Kiểm tra một kế hoạch mới về mặt số học thay vì bằng mắt: tạo với một hạt (seed) cố định trên một thiết bị duy nhất, sau đó tạo lại dưới tensor parallelism, và so sánh các đầu ra. Một <code>"colwise"</code>/<code>"rowwise"</code> đặt sai vị trí thường vẫn chạy và tạo ra một hình ảnh trông hợp lý nhưng sai.</p> <blockquote class="tip"><p>Bắt đầu từ một kế hoạch có sẵn cho một kiến trúc tương tự.</p> <ul><li><a href="https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/transformers/transformer_qwenimage.py" rel="nofollow"><code>transformer_qwenimage.py</code></a> không có các projection đã được hợp nhất, do đó mọi mục đều là <code>"colwise"</code> hoặc <code>"rowwise"</code> thông thường.</li> <li><a href="https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/transformers/transformer_flux.py" rel="nofollow"><code>transformer_flux.py</code></a> thêm một phép chiếu hàng dạng đóng gói.</li> <li><a href="https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/transformers/transformer_flux2.py" rel="nofollow"><code>transformer_flux2.py</code></a> sử dụng cả hai phong cách đóng gói.</li></ul></blockquote> <a class="!text-gray-400 !no-underline text-sm flex items-center not-prose mt-4" href="https://github.com/huggingface/diffusers/blob/main/docs/source/en/optimization/tensor_parallelism.md" target="_blank"><svg class="mr-1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" fill="currentColor" focusable="false" role="img" width="1em" height="1em" preserveAspectRatio="xMidYMid meet" viewBox="0 0 32 32"><path d="M31,16l-7,7l-1.41-1.41L28.17,16l-5.58-5.59L24,9l7,7z"></path><path d="M1,16l7-7l1.41,1.41L3.83,16l5.58,5.59L8,23l-7-7z"></path><path d="M12.419,25.484L17.639,6.552l1.932,0.518L14.351,26.002z"></path></svg><!----> <span><span class="underline">Update</span> on GitHub</span></a><!----> <p></p><!--]--><!----><!--]--><!--]--><!--]--> <!--[-1--><!--]--><!--]--> | |
| <script> | |
| { | |
| __sveltekit_1qsdbwf = { | |
| base: "/docs/diffusers/main/en", | |
| assets: "/docs/diffusers/main/en" | |
| }; | |
| const element = document.currentScript.parentElement; | |
| Promise.all([ | |
| import("/docs/diffusers/main/en/_app/immutable/entry/start.0S0_iEoG.js"), | |
| import("/docs/diffusers/main/en/_app/immutable/entry/app.CPdOxCbw.js") | |
| ]).then(([kit, app]) => { | |
| kit.start(app, element, { | |
| node_ids: [0, 347], | |
| data: [null,null], | |
| form: null, | |
| error: null | |
| }); | |
| }); | |
| } | |
| </script> | |
Xet Storage Details
- Size:
- 40.2 kB
- Xet hash:
- 43357cffb301a06a5b603be8153c6822de8f446098d900ec3341ee808fa3a902
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.