Buckets:

hf-doc-build/doc / diffusers /v0.43.0 /ar /optimization /tensor_parallelism.html
mishig's picture
download
raw
41.6 kB
<meta charset="utf-8" /><meta name="hf:doc:metadata" content="{&quot;title&quot;:&quot;توازي الموتر&quot;,&quot;local&quot;:&quot;tensor-parallelism&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;تحميل نموذج مقسّم&quot;,&quot;local&quot;:&quot;load-a-sharded-model&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;أداء التحميل&quot;,&quot;local&quot;:&quot;loading-performance&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;القيود&quot;,&quot;local&quot;:&quot;limitations&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;إضافة توازي الموترات إلى نموذج&quot;,&quot;local&quot;:&quot;add-tensor-parallelism-to-a-model&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;عمودي وأفقي&quot;,&quot;local&quot;:&quot;colwise-and-rowwise&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;الاستيفاءات المدمجة&quot;,&quot;local&quot;:&quot;fused-projections&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;ما يجب استبعاده&quot;,&quot;local&quot;:&quot;what-to-leave-out&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;قيود والتحقق&quot;,&quot;local&quot;:&quot;constraints-and-verification&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3}],&quot;depth&quot;:2}],&quot;depth&quot;: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="{&quot;title&quot;:&quot;Tensor parallelism&quot;,&quot;local&quot;:&quot;tensor-parallelism&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;Load a sharded model&quot;,&quot;local&quot;:&quot;load-a-sharded-model&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Loading performance&quot;,&quot;local&quot;:&quot;loading-performance&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Limitations&quot;,&quot;local&quot;:&quot;limitations&quot;,&quot;sections&quot;:[],&quot;depth&quot;:2},{&quot;title&quot;:&quot;Add tensor parallelism to a model&quot;,&quot;local&quot;:&quot;add-tensor-parallelism-to-a-model&quot;,&quot;sections&quot;:[{&quot;title&quot;:&quot;Colwise and rowwise&quot;,&quot;local&quot;:&quot;colwise-and-rowwise&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;Fused projections&quot;,&quot;local&quot;:&quot;fused-projections&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;What to leave out&quot;,&quot;local&quot;:&quot;what-to-leave-out&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3},{&quot;title&quot;:&quot;Constraints and verification&quot;,&quot;local&quot;:&quot;constraints-and-verification&quot;,&quot;sections&quot;:[],&quot;depth&quot;:3}],&quot;depth&quot;:2}],&quot;depth&quot;: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><!---->توازي الموتر<!----></span></h1><!--]--><!----> <p>يقوم <a href="https://huggingface.co/spaces/nanotron/ultrascale-playbook?section=tensor_parallelism" rel="nofollow">توازي الموترات</a> بتقسيم مصفوفات الأوزان لنموذج عبر الأجهزة. يحتفظ كل جهاز بشريحة عمودية (<code>"colwise"</code>) أو أفقية (<code>"rowwise"</code>) من كل طبقة ويحسب نتيجة جزئية. يجمع <code>AllReduce</code> أو <code>AllGather</code> عند حدود الطبقة النتائج الجزئية لتكوين المخرجات الكاملة. على عكس <a href="./context_parallelism">توازي السياق</a>، يقلل من ذاكرة <em>الأوزان</em> لكل جهاز، مما يساعد عندما لا يتسع النموذج لجهاز واحد. راجع <a href="../training/distributed_inference">الاستدلال الموزع</a> للمقارنة مع الاستراتيجيات الأخرى.</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><!---->تحميل نموذج مقسّم<!----></span></h2><!--]--><!----> <p>Pass a <a href="/docs/diffusers/v0.43.0/ar/api/parallel#diffusers.TensorParallelConfig">TensorParallelConfig</a> to the <code>parallel_config</code> argument of the model’s <a href="/docs/diffusers/v0.43.0/ar/api/models/overview#diffusers.ModelMixin.from_pretrained">from_pretrained()</a>. <code>tp_degree</code> is the number of devices to shard across and must divide the model’s number of attention heads. The model’s class must define a <code>_tp_plan</code>, which maps module names to a sharding style. To check whether a model supports tensor parallelism, look for this attribute on its class, such as <a href="/docs/diffusers/v0.43.0/ar/api/models/flux2_transformer#diffusers.Flux2Transformer2DModel">Flux2Transformer2DModel</a>.</p> <p>لإضافة خطة إلى نموذج آخر، راجع <a href="#add-tensor-parallelism-to-a-model">إضافة توازي الموترات إلى نموذج</a>.</p> <p>عند التحميل بهذه الطريقة، يتم تقسيم نقطة الحفظ (checkpoint) أثناء قراءتها. يقرأ كل رتبة (rank) شريحتها الخاصة من كل وزن ويضعها مباشرةً على وحدة معالجة الرسوميات (GPU) الخاصة به، لذا لا تحتفظ أي رتبة بوزن بحجمه الكامل. ينخفض حجم الذاكرة لكل رتبة مع زيادة <code>tp_degree</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> تم النسخ</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">&quot;nccl&quot;</span>)
rank, world_size = dist.get_rank(), dist.get_world_size()
<span class="hljs-comment"># torchrun sets LOCAL_RANK to this process&#x27;s GPU index on its node</span>
local_rank = <span class="hljs-built_in">int</span>(os.environ[<span class="hljs-string">&quot;LOCAL_RANK&quot;</span>])
device = torch.device(<span class="hljs-string">f&quot;cuda:<span class="hljs-subst">{local_rank}</span>&quot;</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">&quot;black-forest-labs/FLUX.2-dev&quot;</span>,
subfolder=<span class="hljs-string">&quot;transformer&quot;</span>,
dtype=torch.bfloat16,
parallel_config=TensorParallelConfig(tp_degree=world_size),
)
pipeline = DiffusionPipeline.from_pretrained(
<span class="hljs-string">&quot;black-forest-labs/FLUX.2-dev&quot;</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&#x27;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">&quot;a cat holding a sign that says hello&quot;</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">&quot;output.png&quot;</span>)
dist.destroy_process_group()
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">&quot;__main__&quot;</span>:
main()<!----></pre></div><!----> <p>احفظ السكربت باسم <code>tensor_parallel_flux2.py</code> ثم شغّله باستخدام <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> تم النسخ</div><!----></button><!----></div> <pre class="language-shell "><!---->torchrun --nproc-per-node 4 tensor_parallel_flux2.py<!----></pre></div><!----> <p>يُعيّن السكربت <code>tp_degree</code> إلى <code>world_size</code>، لذا فإن <code>--nproc-per-node 4</code> يُقسّم الترانسفورمر على 4 وحدات معالجة رسومية.</p> <p>يتم تقسيم نموذج التحويل فقط. يحتفظ كل رتبة بنسخة كاملة من مشفّر النص، لذا يحتاج كل معالج رسومي إلى ذاكرة كافية لاستيعاب مشفّر النص بالإضافة إلى حصته من نموذج التحويل.</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><!---->أداء التحميل<!----></span></h2><!--]--><!----> <p>يكون التحميل باستخدام <code>parallel_config</code> أسرع ويستهلك ذاكرة أقل لكل رتبة مقارنة بتحميل النموذج الكامل ثم استدعاء <code>enable_parallelism()</code>. تُظهر الجدول أدناه النتائج الخاصة بـ <a href="https://huggingface.co/black-forest-labs/FLUX.2-dev" rel="nofollow">black-forest-labs/FLUX.2-dev</a> (المحوّل فقط، 32 مليار معامل، bf16) على 4x A10G (23 جيجابايت).</p> <table><thead><tr><th>tp_degree</th><th>طريقة</th><th>وقت التحميل</th><th>ذروة المعالج المركزي/الرتبة</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><!---->القيود<!----></span></h2><!--]--><!----> <p>لا يعمل توازي الموترات مع بعض خيارات التحميل والميزات، ولا يمكن حفظ نموذج مجزأ.</p> <ul><li>لا يعمل التحميل باستخدام <code>parallel_config</code> المتوازي على مستوى الموترات مع <code>device_map</code> أو <code>quantization_config</code> أو <code>low_cpu_mem_usage=False</code> أو <code>use_flashpack=True</code> أو أوزان غير safetensors. فكل واحدة من هذه الخيارات تثير خطأً بدلاً من تحميل نقطة الفحص الكاملة بصمت.</li> <li>يؤدي دمج توازي الموترات مع التكميم أو التفريغ أو محولات LoRA إلى ظهور خطأ، بغض النظر عن كيفية تقسيم النموذج.</li> <li>لتقسيم نموذج موجود مسبقًا في الذاكرة، استدعِ <code>enable_parallelism()</code> باستخدام نفس الإعداد. يقوم هذا بتحميل النموذج الكامل أولًا ثم تقسيمه، لذا يحتاج كل رتبة إلى ذاكرة كافية للنقطة الفحصية الكاملة. التحميل باستخدام <code>parallel_config</code> يتجنب هذا التكلفة.</li> <li>يُطلق حفظ نموذج متوازي الموترات خطأً في <a href="/docs/diffusers/v0.43.0/ar/api/models/overview#diffusers.ModelMixin.save_pretrained">save_pretrained()</a>. احفظ النموذج قبل تقسيمه.</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><!---->إضافة توازي الموترات إلى نموذج<!----></span></h2><!--]--><!----> <p>هذا القسم مخصص للمساهمين الذين يرغبون في إضافة دعم للتوازي الموتر (Tensor Parallelism) إلى نموذج في مكتبة Diffusers.</p> <p>يعمل توازي الموترات فقط على النماذج التي تُعرّف <code>_tp_plan</code>، وهو سمة صنف تُقرن أسماء الوحدات بأسلوب تقسيم. كتابة هذا الخطة تعني في الغالب إقران كل إسقاط <em>يوسّع</em> بُعد المخفي مع الإسقاط الذي <em>يُقلّصه</em> مرة أخرى.</p> <p>يمكن أن تحتوي كل مفتاح على <code>*</code> واحد كحد أقصى، ويجب أن يشير الجزء قبل <code>*</code> إلى <a href="https://pytorch.org/docs/stable/generated/torch.nn.ModuleList.html" rel="nofollow"><code>nn.ModuleList</code></a>، بحيث تغطي كل مدخلة كل كتلة. أما المفتاح الذي لا يحتوي على <code>*</code> فيُطبَّق على النموذج نفسه. والمسارات نسبية بالنسبة إلى النموذج.</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><!---->عمودي وأفقي<!----></span></h3><!--]--><!----> <table><thead><tr><th>الأسلوب</th><th>شرائح</th><th>كل رتبة</th><th>يُستخدم في</th></tr></thead><tbody><tr><td><code>"colwise"</code></td><td>مخرجات الميزات (<code>weight</code> البعد 0)</td><td>يحسب جزءًا من المخرجات</td><td><code>to_q</code>، <code>to_k</code>، <code>to_v</code>، الإسقاط الداخلي لـ FFN</td></tr><tr><td><code>"rowwise"</code></td><td>مُدخلات الميزات (البُعد 1 لـ<code>weight</code>)</td><td>يحسب مجموعاً جزئياً</td><td><code>to_out.0</code>، الإسقاط الخارج للدالة العصبية الأمامية</td></tr><tr><td><code>"rowwise_split_input"</code></td><td>مُدخلات الميزات (البُعد 1 لـ<code>weight</code>)</td><td>يحسب مجموعاً جزئياً من شقّه من المدخل المكرر</td><td>توقع مستقل تكون مدخلاته مكررة، مثل توقع تعديل AdaLN الذي يقرأ تضمين خطوة الزمن</td></tr></tbody></table> <p>يجب دائمًا إقران <code>"colwise"</code> مع <code>"rowwise"</code> بهذا الترتيب. إذ تترك إسقاط <code>"colwise"</code> ناتجه مقسّمًا، بينما يستهلك إسقاط <code>"rowwise"</code> التالي ذلك الجزء مباشرة، ثم يعيد <code>AllReduce</code> واحد عند حدّ الكتلة بناء النتيجة. أما تقسيم الزوج بأي طريقة أخرى فيُجبر على تجميع في المنتصف ويتطلب تواصلًا أكبر بكثير.</p> <p>في الانتباه، تعطي الإسقاطات العمودية لـ Q و K و V كل رتبة مجموعة فرعية من الرؤوس، لذا يجب أن يقسم <code>tp_degree</code> عدد الرؤوس. تتبع النسخ المكررة لتيار المُشفّر (<code>add_q_proj</code>، <code>to_add_out</code>، <code>ff_context</code>) نفس النمط الذي تتبعه نظيراتها في تيار الصورة.</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><!---->الاستيفاءات المدمجة<!----></span></h3><!--]--><!----> <p>عندما يجمع <code>Linear</code> عدة متجهات منطقية على طول البُعد المُجزَّأ، فإن التقسيمات البسيطة <code>"colwise"</code>/<code>"rowwise"</code> تعبر عبر عملية الدمج مباشرةً مما يؤدي إلى عدم محاذاة القطع. استخدم <code>PackedColwiseParallel</code>/<code>PackedRowwiseParallel</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> تم النسخ</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>مرّر <code>blocks</code>، وهو قائمة من الأعداد الصحيحة النسبية التي يقبل مجموعها القسمة على البُعد المُجمَّع. على سبيل المثال، استخدم <code>[1, 1]</code> لبوابة SwiGLU وتحويل تصاعدي بنصفين متساويين، أو استخدم <code>[1, 1, 1, 3, 3]</code> لتحويل Q وK وV وبوابة وتحويل تصاعدي مُدمجة مع <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> تم النسخ</div><!----></button><!----></div> <pre class="language-py "><!----><span class="hljs-string">&quot;transformer_blocks.*.ff.linear_in&quot;</span>: PackedColwiseParallel([<span class="hljs-number">1</span>, <span class="hljs-number">1</span>]),<!----></pre></div><!----> <p>عندما تكون أحجام الكتل معروفة فقط من ملف الإعداد، احذف <code>blocks</code> وخزّن الأحجام المطلقة على <code>Linear</code> أثناء <code>__init__</code> بدلاً من ذلك، كـ <code>_tp_packed_col_blocks</code> أو <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> تم النسخ</div><!----></button><!----></div> <pre class="language-py "><!----><span class="hljs-comment"># in the attention module&#x27;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> تم النسخ</div><!----></button><!----></div> <pre class="language-py "><!----><span class="hljs-comment"># in the model&#x27;s _tp_plan</span>
<span class="hljs-string">&quot;single_transformer_blocks.*.attn.to_out&quot;</span>: PackedRowwiseParallel(),<!----></pre></div><!----> <p>يستخدم الخطة في <a href="https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/transformers/transformer_flux2.py" rel="nofollow"><code>transformer_flux2.py</code></a> كلا الشكلين. يمرر زوج SwiGLU ذو التدفق المزدوج <code>blocks</code> مباشرةً. أما إسقاط QKV و MLP المدمج ذو التدفق الأحادي فيخزّن أحجامه على <code>Linear</code> داخل <code>Flux2ParallelSelfAttention.__init__</code>، وذلك لأنها تعتمد على <code>mlp_ratio</code> و<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><!---->ما يجب استبعاده<!----></span></h3><!--]--><!----> <p>يتم تكرار الوحدات غير المدرجة في الخطة على كل رتبة. اترك طبقات التطبيع، وتضمينات البقع والنص، والطبقتين الأخيرتين <code>norm_out</code> و<code>proj_out</code>. فهي صغيرة، لذا فإن تقسيمها يوفر القليل من الذاكرة ويضيف اتصالات. تعديل AdaLN (<code>img_mod</code> و<code>txt_mod</code>) يكون عادةً صغيرًا بما يكفي ليُترك خارج الخطة أيضًا. عندما يكون كبيرًا، مثل <code>adaln_proj.linear</code> في MiniMax-H3، قسّمه باستخدام <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><!---->قيود والتحقق<!----></span></h3><!--]--><!----> <ul><li>يجب أن يقسم <code>tp_degree</code> <code>config.num_attention_heads</code>.</li> <li>يجب أن يكون كل كتلة مكدّسة <em>بشكل فردي</em> قابلة للقسمة على <code>tp_degree</code>، وليس مجموعها فقط.</li></ul> <p><a href="/docs/diffusers/v0.43.0/ar/api/models/overview#diffusers.ModelMixin.from_pretrained">from_pretrained()</a> و<code>enable_parallelism()</code> يتحققان من كلا الأمرين قبل تحميل أي وزن أو تقسيمه.</p> <p>تحقّق رقمياً من خطة جديدة بدلاً من التحقق البصري: ولّد النتائج باستخدام بذرة ثابتة على جهاز واحد، ثم أعد التوليد تحت توازي الموترات، وقارن المخرجات. غالباً ما يؤدي وضع <code>"colwise"</code>/<code>"rowwise"</code> في المكان الخطأ إلى تشغيل النموذج وإنتاج صورة تبدو معقولة لكنها خاطئة.</p> <blockquote class="tip"><p>ابدأ من خطة موجودة مسبقًا لهندسة معمارية مشابهة.</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> على إسقاطات مدمجة، لذا كل عنصر هو ببساطة <code>"colwise"</code> أو <code>"rowwise"</code>.</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> إسقاطًا صفّيًا مكدّسًا واحدًا.</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> كلا الأسلوبين المعبّأة.</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:
41.6 kB
·
Xet hash:
bdec152726b51966b672d12694d440f252bd39efdac496f76c261f2eeefb7d00

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.