From a867c5dc70776fc8c279b6e87f3161063357c647 Mon Sep 17 00:00:00 2001 From: lichuyang Date: Wed, 9 Sep 2026 16:19:33 +0800 Subject: [PATCH 1/9] =?UTF-8?q?[feature]=20=E8=BF=81=E7=A7=BB=20DiffSynth-?= =?UTF-8?q?Studio=20Quick=20Start=20=E5=B9=B6=E6=8E=A5=E5=85=A5=E7=9C=8B?= =?UTF-8?q?=E6=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 把 modelscope/DiffSynth-Studio 的昇腾 Quick Start 迁到本仓,模型改为 Hugging Face,并接到共享 quick-start 引擎。 --- .../diffsynth_studio-quick-start.yml | 68 ++++++ _static/images/diffsynth_studio.png | Bin 0 -> 2692 bytes conf.py | 3 +- index.rst | 8 + sources/diffsynth_studio/index.rst | 2 + sources/diffsynth_studio/quick_start.md | 227 ++++++++++++++++++ tests/diffsynth_studio/__init__.py | 29 +++ .../test_quick_start_ascend.py | 113 +++++++++ 8 files changed, 449 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/diffsynth_studio-quick-start.yml create mode 100644 _static/images/diffsynth_studio.png create mode 100644 sources/diffsynth_studio/index.rst create mode 100644 sources/diffsynth_studio/quick_start.md create mode 100644 tests/diffsynth_studio/__init__.py create mode 100644 tests/diffsynth_studio/test_quick_start_ascend.py diff --git a/.github/workflows/diffsynth_studio-quick-start.yml b/.github/workflows/diffsynth_studio-quick-start.yml new file mode 100644 index 000000000..7e141ce0c --- /dev/null +++ b/.github/workflows/diffsynth_studio-quick-start.yml @@ -0,0 +1,68 @@ +# diffsynth_studio quick start guard - project thin trigger. +# +# Calls the common engine .github/workflows/quick-start-template.yml; + +name: diffsynth_studio-quick-start + +concurrency: + # format() is load-bearing: a '||' between 'manual-' and + # github.run_id would short-circuit on the truthy literal and + # every dispatch would share one 'manual-' group. + group: ${{ github.event_name == 'schedule' && 'diffsynth_studio-quick-start-schedule' || format('manual-{0}', github.run_id) }} + # cancel-in-progress: false because (1) a schedule run cancelled + # mid-way loses its outcome writeback - the outcome is what makes + # the retry mechanism work, and the 'if: always()' guard isn't + # enough when the container is being torn down; (2) dispatch / PR + # runs already live in unique groups so there's nothing to cancel. + cancel-in-progress: false + +on: + schedule: + # Offset from peft's '30 */3 * * *' and llama_cpp's '45 */3 * * *'. + - cron: '20 */3 * * *' + workflow_dispatch: + # PR trigger: docs/tests changes get a guard run. paths filter avoids burning + # the self-hosted NPU runner on unrelated PRs. `pull_request` (not + # `pull_request_target`): contents: read is enough, no write-token risk. + pull_request: + branches: [main] + paths: + - 'sources/diffsynth_studio/**' + - 'tests/diffsynth_studio/**' + +permissions: + contents: read + +jobs: + diffsynth_studio-quick-start: + uses: ./.github/workflows/quick-start-template.yml + with: + # Namespaces cache keys (monitor-state-diffsynth_studio-*), artifacts + # (diffsynth_studio-quick-start-) and the test working dir + # (workflows/tests/diffsynth_studio). + project: diffsynth_studio + # Self-hosted NPU runner for the test job only; the engine pins + # the cache I/O jobs (restore-cache / publish-and-persist) to + # GitHub-hosted ubuntu-latest. + test_runner: '["linux-aarch64-a2-1"]' + image: swr.cn-south-1.myhuaweicloud.com/ascendhub/cann:9.1.0-910b-ubuntu22.04-py3.12 + # 2 h budget. Cold path is torch-npu wheels plus a ~4 GB Hugging Face + # snapshot of stable-diffusion-v1-5, then five SD inference steps. + # Do not add a container bind-mount for /root/.cache: the runner + # NFS already persists that tree. Hub files reuse the default + # /root/.cache/huggingface/hub layout. + timeout_minutes: 120 + upstream_repo: modelscope/DiffSynth-Studio + # Doc URL points to the upstream Ascend/docs repo. {0} is filled by the + # engine: PR head SHA on PR runs, 'main' otherwise. Same-repo PRs (head + # SHA exists on Ascend/docs) test the PR-version of the doc; fork PRs + # (head SHA on a fork) 404 on doc fetch - accepted, since the content + # lands on Ascend/docs post-merge. + doc_url: 'https://raw.githubusercontent.com/Ascend/docs/{0}/sources/diffsynth_studio/quick_start.md' + doc_path: https://github.com/Ascend/docs/blob/main/sources/diffsynth_studio/quick_start.md + # cwd is the repo root inside the `workflows` checkout (matches + # engine template's `working-directory: workflows`); env contract + # (MONITORED_DOC_URL / UPSTREAM_REF / NPU_READY) is injected by the + # engine. All project env prep lives in the test subclass's + # prepare_environment hook. + test_command: python -m unittest tests.diffsynth_studio.test_quick_start_ascend -v 2>&1 diff --git a/_static/images/diffsynth_studio.png b/_static/images/diffsynth_studio.png new file mode 100644 index 0000000000000000000000000000000000000000..c0662d91ea2c41bced657a5221efec90d9c0d57f GIT binary patch literal 2692 zcmcImX;4#F7`+Lmqyz-3Bxpf`rOkANFbY;=k;p)WD#R+{#$u~2i`3L2peB&m($T5~ zDl<5>h*DW>DT^qwyFh_ZEksi`4WI@{fDo1{2}?-teZD8LGo9&7r$4^A$@lL4?tSN+ z@7(vzmcWf>Cd*6!0A~JvK3f4G-9teo!%Rn|`F#LPHu?K(2s)Cf>TWH_kLzw4AFdk6 zTsLRMEN@HAHA4j z-_u)y9#C1+AF*fG$aBs(D>6sd{wnrWSRHRI8WtS&2)-tef7c-xcz#q^bge9`*cdEJ zPopR|%UxSMjczx7ah5_2h&2Z#&3{mU9cz~;Es)O4VFT(8r`J8;DQbY|aE+RFtfT?Mee>zc{QnQ$@trePhtoWYRQMo#u9pkVtMEPoxIB#lC? z)RM6XC}@jTF9q+lUtt4f1x(`4(cp;(+}NP*4S0SOH|r=C6P9dI+G!`OVi$Zj6zF`1 zOMzV+344p2^!X#eeev?dWCR9&xITND1p*D7%pgqw69`Kp6!F~*jyYcyB_qm!U28On zs7fry5l5h*kVcoC=f5WUcFoT;;Pxt#`?-)67-*%zE+dcu6vdyDlIc3jB9`qVFJV%p z-0{xj)?7`_0lZal<;SvbkKR@Ao^;{E(Y~R@ z-tk7dDQ0b2axs9@FBDk30b#JCVFNK40*#(* zWdKYU2q;E4hCh);3dHHaP#&ik*1^lo4->yY@$GVaSruRICnhI1j_TB^KY2B)G*-rZ zIV&Q}wR(+aNqxjYwPZ-00T1J=T0Iqkwy+Ls!g{dnvRnC7t^I$@p`t zI~#Pmj*Ro642?!Vu810eo#AX2Tme=~U0s{WLGLW3Nv=XULU6L9Bn+@W24WE+ASLJB z*+6GHH}4d+hNpxluE)y_cWA?#XV&40J8Zi9)Md!Js++1X|kBh?~wF*Adp5w?ZKSDRDfVp>oc0Xla|udD)M zt?wyd*R)fVhBJXI56y3)V$G4=ypDcJj+k)Tx_~-`Ca(;c4}*?EY@?W6;VY7~8?Sfm zIXuuQ+h?sZzZG7qeL8DAvghCr2Wz4#g_enZefoQzb=g@*1v;6!2g*D~*Xw>-$4!77 z$lkJ!E?c%-*RUcfZ->e>AxV(k6<0r4zIb0qVX(YHvU}3qJoMPWV4G~4X}ES`(o^#p zg#Wu|g}gAg8P%-U9iwjj)CgDDnEJf;M!CCSFqQ$?3o!SnNF2>ixy}82cT62QM$|vI z(rT~K=HchFxvblHf47AB7B{dFJc&FLp-eP8?kLF)9Mt!ynXraxi(aEK1#ccW|4x|$ z$G480j8A|A#v$bKA8ac837I+t>GgZD2+@xPyy=KL0$JAu2TtUs&@rdlxrfua4Epqr z`>qRFTt^M-NZa=M=3%;9PfLqzv9)?4_eos=O&5NUmyrFHV|%;I$eNVuQKJ#p^JBS( zN}!8)X~!+$&nrBS>yPdCl=QBz)pzs4v-l=GHqZqKMWB{NsxaUj-LC(uiz2X)*kMHO zE)0HQLs47rl7sADz>R~7gxC1?2~~RP$VIPPvhj?)e146*WnV1!PPIyQcQ`+*^CJIL zZuM0A;Ir@F8sm-oo^ZJRVZwsB<-oNHuYs&k@HLIuM+h8s1mwIF5{v>}xr6Y9@edC_ zXhTRgNCxwAAtn<~{&txdq=_rX5X1R8|5官方链接|安装指南|快速上手 + +
+

DiffSynth-Studio

+

ModelScope 的扩散模型引擎,支持在昇腾 NPU 上文生图。

+ +
+

lm-evaluation-harness

@@ -463,6 +470,7 @@ :caption: 🎨 多模态、应用与评测 sources/Diffusers/index.rst + sources/diffsynth_studio/index.rst sources/lm_evaluation/index.rst sources/open_clip/index.rst sources/opencompass/index.rst diff --git a/sources/diffsynth_studio/index.rst b/sources/diffsynth_studio/index.rst new file mode 100644 index 000000000..89892f3b6 --- /dev/null +++ b/sources/diffsynth_studio/index.rst @@ -0,0 +1,2 @@ +.. include:: quick_start.md + :parser: myst_parser.sphinx_ diff --git a/sources/diffsynth_studio/quick_start.md b/sources/diffsynth_studio/quick_start.md new file mode 100644 index 000000000..dd2b2b9a3 --- /dev/null +++ b/sources/diffsynth_studio/quick_start.md @@ -0,0 +1,227 @@ +# DiffSynth-Studio + +在单卡昇腾上安装 [DiffSynth-Studio](https://github.com/modelscope/DiffSynth-Studio),用 Stable Diffusion 1.5 生成一张图。 + + +## 前置条件 + +### 硬件 + +Atlas **800T** / **900 A2** 训练系列(Ascend **910B**)。本文示例为单卡。 + +### 软件 + +| 类别 | 要求 | +| --- | --- | +| CANN | toolkit + 驱动固件已安装,并可 `source set_env.sh` | +| Python | 3.12 | +| PyTorch | `torch==2.9.0` 与 `torch_npu==2.9.0.post2`,见下文安装 | +| DiffSynth-Studio | 从 PyPI 安装 `diffsynth`,见下文 | +| 模型 | [stable-diffusion-v1-5/stable-diffusion-v1-5](https://huggingface.co/stable-diffusion-v1-5/stable-diffusion-v1-5) | + +阅读本文前,请先按 [快速安装昇腾环境](https://ascend.github.io/docs/sources/ascend/quick_install.html) 准备好 CANN 与驱动。推荐配套镜像:`swr.cn-south-1.myhuaweicloud.com/ascendhub/cann:9.1.0-910b-ubuntu22.04-py3.12`。 + +## 1. 加载 CANN 环境 + +常见容器里 `npu-smi` 在 `/usr/local/sbin`,需要把该目录加入 `PATH`。 + +```shell +source /usr/local/Ascend/ascend-toolkit/set_env.sh +export PATH=/usr/local/sbin:$PATH +``` + +## 2. 检查环境是否就绪 + +### 2.1 确认 NPU 在线 + +```shell +npu-smi info +``` + +如果 `npu-smi` 找不到,回到 [快速安装昇腾环境](https://ascend.github.io/docs/sources/ascend/quick_install.html) 检查驱动与设备挂载。 + + +### 2.2 确认工具可用 + +下面确认 CANN 已加载,并且 `npu-smi` 与 `python` 都在 `PATH` 里。 + +```shell #test id="check-tools" +test -n "$ASCEND_HOME_PATH" +command -v npu-smi >/dev/null +python --version +``` + +输出结果如下: + +```shell #test-result id="check-tools" +Python 3.12... +``` + +## 3. 安装 PyTorch NPU 栈 + +从昇腾 PyPI 源安装与 CANN 9.1 配对的 `torch` / `torch_npu`,并确认 NPU 运行时可用。 + +```shell #test id="install-torch" +python -m pip install --retries 3 \ + --extra-index-url https://repo.huaweicloud.com/ascend/repos/pypi \ + torch==2.9.0 torch_npu==2.9.0.post2 torchvision numpy pyyaml +python -c "import numpy, yaml, torch, torch_npu; print('torch', torch.__version__); print('torch_npu', torch_npu.__version__); print('npu_available', torch.npu.is_available())" +``` + +输出结果如下: + +```shell #test-result id="install-torch" +... +torch 2.9.0... +torch_npu 2.9.0.post2 +npu_available True +``` + +`npu_available` 必须是 `True`。为 `False` 时不要继续,先查 CANN、驱动和可见设备。 + +## 4. 安装 DiffSynth-Studio + +不要运行 `pip install -e ".[npu_aarch64]"`。那个 extra 会把刚装好的 `torch 2.9.0` 降回 `2.7.1`。先装好上一节的 NPU 栈,再装不带 extra 的 `diffsynth`。 + +```shell #test id="install-diffsynth" +python -m pip install --retries 3 diffsynth +python -c "import torch, torch_npu; from importlib.metadata import version; from diffsynth.core.device.npu_compatible_device import get_device_name, get_device_type; print('diffsynth', version('diffsynth')); print('device_type', get_device_type()); print('device_name', get_device_name())" +``` + +输出结果如下: + +```shell #test-result id="install-diffsynth" +... +diffsynth ... +device_type npu +device_name npu:0 +``` + +`device_name` 为 `npu:0` 只说明设备探测成功。若这里打印 `device_type cpu` 或 `cuda`,先回到第 3 节确认 `torch_npu` 和可见设备。 + +## 5. 在 NPU 上生成一张图 + +`num_inference_steps=5` 是第一次跑通的步数。50 步出图更清楚,但第一次验证安装不必等那么久。正式出图时把步数改回 `50`。权重从 Hugging Face 下载,脚本里把 `download_source` 设为 `huggingface`。 + +保存为 `generate_sd15.py`: + +```python +import torch +import torch_npu +from diffsynth.core import ModelConfig +from diffsynth.core.device.npu_compatible_device import get_device_name +from diffsynth.pipelines.stable_diffusion import StableDiffusionPipeline + +print("device_name", get_device_name()) +pipe = StableDiffusionPipeline.from_pretrained( + torch_dtype=torch.float32, + device="npu", + model_configs=[ + ModelConfig( + model_id="stable-diffusion-v1-5/stable-diffusion-v1-5", + origin_file_pattern="text_encoder/model.safetensors", + download_source="huggingface", + ), + ModelConfig( + model_id="stable-diffusion-v1-5/stable-diffusion-v1-5", + origin_file_pattern="unet/diffusion_pytorch_model.safetensors", + download_source="huggingface", + ), + ModelConfig( + model_id="stable-diffusion-v1-5/stable-diffusion-v1-5", + origin_file_pattern="vae/diffusion_pytorch_model.safetensors", + download_source="huggingface", + ), + ], + tokenizer_config=ModelConfig( + model_id="stable-diffusion-v1-5/stable-diffusion-v1-5", + origin_file_pattern="tokenizer/", + download_source="huggingface", + ), +) +print("pipe.device", pipe.device) +print("unet.device", next(pipe.unet.parameters()).device) +image = pipe( + prompt="a photo of an astronaut riding a horse on mars, high quality, detailed", + negative_prompt="blurry, low quality, deformed", + cfg_scale=7.5, + height=512, + width=512, + seed=42, + rand_device="npu", + num_inference_steps=5, +) +image.save("image.jpg") +print("image_size", image.size) +``` + + + +```shell #test id="generate" +python generate_sd15.py +``` + +输出结果如下: + +```shell #test-result id="generate" +device_name npu:0 +... +pipe.device npu +unet.device npu:0 +image_size (512, 512) +... +``` + +`pipe.device` 打印的是传入的字符串 `npu`。`unet.device` 才是参数真正所在的设备。 diff --git a/tests/diffsynth_studio/__init__.py b/tests/diffsynth_studio/__init__.py new file mode 100644 index 000000000..630473671 --- /dev/null +++ b/tests/diffsynth_studio/__init__.py @@ -0,0 +1,29 @@ +"""Tests package marker. + +Single responsibility: inject the repo's ``tests/`` into ``sys.path`` +so that ``from doc_test.base import ...`` can resolve. + +Framework deps (mistune) are installed by the common quick-start workflow +template, not at import time here. + +Why it lives here: +* unittest treats ``tests/`` as a package; the parent ``__init__.py`` + executes before any submodule import. +* It runs before ``tests/test_*.py`` import, which is the earliest + opportunity to inject ``sys.path``. +""" + +from __future__ import annotations + +import sys +from pathlib import Path + +# sys.path bootstrap: make ``doc_test.*`` resolvable. +# Layout: tests/diffsynth_studio/__init__.py -> parents[0]=tests/diffsynth_studio, +# parents[1]=tests, parents[2]=repo root. +_REPO_ROOT = Path(__file__).resolve().parents[2] +_TESTS_ROOT = _REPO_ROOT / 'tests' +for _p in (_TESTS_ROOT, _REPO_ROOT): + _ps = str(_p) + if _ps not in sys.path: + sys.path.insert(0, _ps) diff --git a/tests/diffsynth_studio/test_quick_start_ascend.py b/tests/diffsynth_studio/test_quick_start_ascend.py new file mode 100644 index 000000000..92db00538 --- /dev/null +++ b/tests/diffsynth_studio/test_quick_start_ascend.py @@ -0,0 +1,113 @@ +"""Quick-start test: doc under test is ``sources/diffsynth_studio/quick_start.md``. + +Run: ``python -m unittest tests.diffsynth_studio.test_quick_start_ascend -v 2>&1`` + +Env (injected by the engine ``quick-start-template.yml``, triggered by +``diffsynth_studio-quick-start.yml``): ``MONITORED_DOC_URL``, ``UPSTREAM_REF``, +``NPU_READY=true`` (otherwise the class is skipped). +""" + +from __future__ import annotations + +import os +import subprocess +import unittest + +from doc_test.base import MarkdownDocTestBase +from doc_test.model_cache import ( + ensure_safetensors, + purge_huggingface_corrupt, + report_huggingface_state, + resolve_huggingface_cache, +) + + +def _is_truthy(value: str | None) -> bool: + """``'true'`` -> True (case-insensitive); anything else (including unset) -> False.""" + if not value: + return False + return value.strip().lower() == 'true' + + +def _e2e_enabled() -> bool: + """Return True when ``NPU_READY=true`` is set, releasing the skip.""" + return _is_truthy(os.environ.get('NPU_READY')) + + +class TestQuickStartAscend(MarkdownDocTestBase, unittest.TestCase): + """End-to-end test: fetch doc -> validate contract -> run ``#test-setup`` + / ``#test`` in order -> compare against ``#test-result``.""" + + # Cold Hugging Face snapshot of SD 1.5 plus five inference steps. + DEFAULT_COMMAND_TIMEOUT = 7200 + USER_AGENT = 'ascend-docs/quick-start' + ERROR_MARKERS = ( + *MarkdownDocTestBase.ERROR_MARKERS, + 'applicaiton exception', # typo in CANN's Python driver (sic) + 'ERR99999', # CANN sentinel for unrecoverable runtime failure + ) + + _MODEL_ID = 'stable-diffusion-v1-5/stable-diffusion-v1-5' + _CANN_SET_ENV = '/usr/local/Ascend/ascend-toolkit/set_env.sh' + + @classmethod + def prepare_environment(cls) -> None: + """Source CANN env once so later ``bash -c`` blocks inherit it. + + Class-level setup: run once per test class, triggered by + ``setUpClass``. Each labeled fence is a new subprocess, so a + ``source set_env.sh`` block in the document does not persist. + + Merge is overwrite, not ``setdefault``: the container image may + already ship ``LD_LIBRARY_PATH``, which would otherwise hide the + CANN increment from ``set_env.sh``. + """ + os.environ['PYTHONNOUSERSITE'] = '1' + + if os.path.isfile(cls._CANN_SET_ENV): + merged = subprocess.run( + ['bash', '-c', f'source {cls._CANN_SET_ENV} >/dev/null 2>&1; env'], + capture_output=True, text=True, check=True, + ) + for line in merged.stdout.splitlines(): + if '=' not in line: + continue + key, _, value = line.partition('=') + os.environ[key] = value + print('setup: sourced CANN env from set_env.sh') + else: + print( + f'setup: skipping CANN env source ({cls._CANN_SET_ENV} not present)' + ) + + path_dirs = '/usr/local/sbin:/usr/local/bin' + current_path = os.environ.get('PATH', '') + if path_dirs not in current_path: + os.environ['PATH'] = f'{path_dirs}:{current_path}' + + ensure_safetensors() + report_huggingface_state(cls._MODEL_ID) + purge_huggingface_corrupt(resolve_huggingface_cache()) + + @classmethod + def setUpClass(cls) -> None: + """Run env setup once per class. ``@unittest.skipIf`` only skips + the test *method* — ``setUpClass`` itself always runs, so the + ``if _e2e_enabled()`` guard keeps heavy setup from firing when + ``NPU_READY`` is unset. + """ + if _e2e_enabled(): + cls.prepare_environment() + + @unittest.skipIf( + not _e2e_enabled(), + 'end-to-end requires NPU runner; set NPU_READY=true', + ) + def test_runs_doc(self) -> None: + """Run the full pre_process -> parse -> execute -> post_process flow.""" + + self.run_template() + + +if __name__ == '__main__': + unittest.main() From b07220a3645127397935aef4f15c39920c55564c Mon Sep 17 00:00:00 2001 From: lichuyang Date: Thu, 24 Sep 2026 10:57:11 +0800 Subject: [PATCH 2/9] =?UTF-8?q?docs(diffsynth):=20=E6=8C=89=E8=AF=84?= =?UTF-8?q?=E5=AE=A1=E6=94=B9=E6=A0=B7=E4=BE=8B=E3=80=81=E5=AE=89=E8=A3=85?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E5=92=8C=E7=94=9F=E6=88=90=E6=AD=A5=E9=AA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit npu-smi 只给读者看样例。PyTorch 改从 CPU 轮子源安装,预期要求版本号带 +cpu。生成改成直接执行一段 Python。 --- sources/diffsynth_studio/quick_start.md | 149 ++++++------------ .../test_quick_start_ascend.py | 2 - 2 files changed, 52 insertions(+), 99 deletions(-) diff --git a/sources/diffsynth_studio/quick_start.md b/sources/diffsynth_studio/quick_start.md index dd2b2b9a3..cbb78b4f4 100644 --- a/sources/diffsynth_studio/quick_start.md +++ b/sources/diffsynth_studio/quick_start.md @@ -1,29 +1,33 @@ # DiffSynth-Studio -在单卡昇腾上安装 [DiffSynth-Studio](https://github.com/modelscope/DiffSynth-Studio),用 Stable Diffusion 1.5 生成一张图。 +[DiffSynth-Studio](https://github.com/modelscope/DiffSynth-Studio) 是 ModelScope 的扩散模型引擎,用于文生图等生成任务。本文在单卡昇腾上安装它,并用 Stable Diffusion 1.5 生成一张图。 ## 前置条件 ### 硬件 -Atlas **800T** / **900 A2** 训练系列(Ascend **910B**)。本文示例为单卡。 +Atlas 800T / 900 A2 训练系列,Ascend 910B。本文示例为单卡。 ### 软件 | 类别 | 要求 | | --- | --- | -| CANN | toolkit + 驱动固件已安装,并可 `source set_env.sh` | -| Python | 3.12 | -| PyTorch | `torch==2.9.0` 与 `torch_npu==2.9.0.post2`,见下文安装 | -| DiffSynth-Studio | 从 PyPI 安装 `diffsynth`,见下文 | +| CANN | toolkit 与驱动已安装,并能 `source set_env.sh`。版本按 [昇腾软件配套清单](https://www.hiascend.com/developer/download/compatibility) 选择 | +| Python | 落在官方配套表范围内,并满足 DiffSynth-Studio 下限。当前正式版要求 3.10.1 及以上 | +| PyTorch | 安装官方当前推荐的 `torch` 与 `torch_npu`,CPU 轮子的版本号带 `+cpu`。见 [CANN 与 PyTorch 配套表](https://github.com/Ascend/pytorch/blob/master/COMPATIBILITY.md) 和 [PyTorch 安装包](https://www.hiascend.com/developer/software/ai-frameworks/pytorch/download) | +| DiffSynth-Studio | 从 PyPI 安装 `diffsynth` | | 模型 | [stable-diffusion-v1-5/stable-diffusion-v1-5](https://huggingface.co/stable-diffusion-v1-5/stable-diffusion-v1-5) | -阅读本文前,请先按 [快速安装昇腾环境](https://ascend.github.io/docs/sources/ascend/quick_install.html) 准备好 CANN 与驱动。推荐配套镜像:`swr.cn-south-1.myhuaweicloud.com/ascendhub/cann:9.1.0-910b-ubuntu22.04-py3.12`。 +阅读本文前,请先按 [快速安装昇腾环境](https://ascend.github.io/docs/sources/ascend/quick_install.html) 准备好 CANN 与驱动。 + +### 本文验证环境 + +看护镜像为 `swr.cn-south-1.myhuaweicloud.com/ascendhub/cann:9.1.0-910b-ubuntu22.04-py3.12`。该镜像自带 Python 3.12。torch 使用 CPU 轮子,版本号以 `+cpu` 结尾。这组版本不是唯一支持组合。 ## 1. 加载 CANN 环境 -常见容器里 `npu-smi` 在 `/usr/local/sbin`,需要把该目录加入 `PATH`。 +加载 CANN,并把 `/usr/local/sbin` 加入 PATH。 ```shell source /usr/local/Ascend/ascend-toolkit/set_env.sh @@ -38,126 +42,81 @@ export PATH=/usr/local/sbin:$PATH npu-smi info ``` -如果 `npu-smi` 找不到,回到 [快速安装昇腾环境](https://ascend.github.io/docs/sources/ascend/quick_install.html) 检查驱动与设备挂载。 - +输出类似: + +```text ++------------------------------------------------------------------------------------------------+ +| npu-smi 25.5.2 Version: 25.5.2 | ++---------------------------+---------------+----------------------------------------------------+ +| NPU Name | Health | Power(W) Temp(C) Hugepages-Usage(page)| +| Chip | Bus-Id | AICore(%) Memory-Usage(MB) HBM-Usage(MB) | ++===========================+===============+====================================================+ +| 5 910B4 | OK | 89.9 39 0 / 0 | +| 0 | 0000:41:00.0 | 0 0 / 0 2922 / 32768 | ++===========================+===============+====================================================+ ++---------------------------+---------------+----------------------------------------------------+ +| NPU Chip | Process id | Process name | Process memory(MB) | ++===========================+===============+====================================================+ +| No running processes found in NPU 5 | ++===========================+===============+====================================================+ +``` -### 2.2 确认工具可用 +如果 `npu-smi` 找不到,回到 [快速安装昇腾环境](https://ascend.github.io/docs/sources/ascend/quick_install.html) 检查驱动与设备挂载。 -下面确认 CANN 已加载,并且 `npu-smi` 与 `python` 都在 `PATH` 里。 +### 2.2 确认 CANN 已加载 -```shell #test id="check-tools" +```shell test -n "$ASCEND_HOME_PATH" -command -v npu-smi >/dev/null -python --version ``` -输出结果如下: - -```shell #test-result id="check-tools" -Python 3.12... -``` +命令成功时没有输出。 ## 3. 安装 PyTorch NPU 栈 -从昇腾 PyPI 源安装与 CANN 9.1 配对的 `torch` / `torch_npu`,并确认 NPU 运行时可用。 +安装 `torch_npu`、`torchvision`、`numpy` 与 `pyyaml`,并打印 `torch`、`torch_npu` 和 `npu_available`。 ```shell #test id="install-torch" python -m pip install --retries 3 \ - --extra-index-url https://repo.huaweicloud.com/ascend/repos/pypi \ - torch==2.9.0 torch_npu==2.9.0.post2 torchvision numpy pyyaml + --index-url https://download.pytorch.org/whl/cpu \ + --extra-index-url https://pypi.org/simple \ + torch_npu torchvision numpy pyyaml python -c "import numpy, yaml, torch, torch_npu; print('torch', torch.__version__); print('torch_npu', torch_npu.__version__); print('npu_available', torch.npu.is_available())" ``` -输出结果如下: +完整输出较长,其中应包含: ```shell #test-result id="install-torch" ... -torch 2.9.0... -torch_npu 2.9.0.post2 +torch ...+cpu +torch_npu ... npu_available True ``` -`npu_available` 必须是 `True`。为 `False` 时不要继续,先查 CANN、驱动和可见设备。 +`npu_available` 为 True。 ## 4. 安装 DiffSynth-Studio -不要运行 `pip install -e ".[npu_aarch64]"`。那个 extra 会把刚装好的 `torch 2.9.0` 降回 `2.7.1`。先装好上一节的 NPU 栈,再装不带 extra 的 `diffsynth`。 +安装 PyPI 上的 `diffsynth`,并打印设备类型和设备名。 ```shell #test id="install-diffsynth" python -m pip install --retries 3 diffsynth python -c "import torch, torch_npu; from importlib.metadata import version; from diffsynth.core.device.npu_compatible_device import get_device_name, get_device_type; print('diffsynth', version('diffsynth')); print('device_type', get_device_type()); print('device_name', get_device_name())" ``` -输出结果如下: - + ## 5. 在 NPU 上生成一张图 -`num_inference_steps=5` 是第一次跑通的步数。50 步出图更清楚,但第一次验证安装不必等那么久。正式出图时把步数改回 `50`。权重从 Hugging Face 下载,脚本里把 `download_source` 设为 `huggingface`。 - -保存为 `generate_sd15.py`: - -```python -import torch -import torch_npu -from diffsynth.core import ModelConfig -from diffsynth.core.device.npu_compatible_device import get_device_name -from diffsynth.pipelines.stable_diffusion import StableDiffusionPipeline - -print("device_name", get_device_name()) -pipe = StableDiffusionPipeline.from_pretrained( - torch_dtype=torch.float32, - device="npu", - model_configs=[ - ModelConfig( - model_id="stable-diffusion-v1-5/stable-diffusion-v1-5", - origin_file_pattern="text_encoder/model.safetensors", - download_source="huggingface", - ), - ModelConfig( - model_id="stable-diffusion-v1-5/stable-diffusion-v1-5", - origin_file_pattern="unet/diffusion_pytorch_model.safetensors", - download_source="huggingface", - ), - ModelConfig( - model_id="stable-diffusion-v1-5/stable-diffusion-v1-5", - origin_file_pattern="vae/diffusion_pytorch_model.safetensors", - download_source="huggingface", - ), - ], - tokenizer_config=ModelConfig( - model_id="stable-diffusion-v1-5/stable-diffusion-v1-5", - origin_file_pattern="tokenizer/", - download_source="huggingface", - ), -) -print("pipe.device", pipe.device) -print("unet.device", next(pipe.unet.parameters()).device) -image = pipe( - prompt="a photo of an astronaut riding a horse on mars, high quality, detailed", - negative_prompt="blurry, low quality, deformed", - cfg_scale=7.5, - height=512, - width=512, - seed=42, - rand_device="npu", - num_inference_steps=5, -) -image.save("image.jpg") -print("image_size", image.size) -``` +用 Python 执行以下代码。种子为 42,推理 5 步,高和宽都是 512。权重从 Hugging Face 下载。 - - -```shell #test id="generate" -python generate_sd15.py ``` -输出结果如下: +完整输出较长,其中应包含: -```shell #test-result id="generate" +```text #test-result id="generate" device_name npu:0 ... pipe.device npu @@ -224,4 +177,6 @@ image_size (512, 512) ... ``` -`pipe.device` 打印的是传入的字符串 `npu`。`unet.device` 才是参数真正所在的设备。 +## 6. 更多用法 + +本文演示的是单卡上用 Stable Diffusion 1.5 生成一张图。LoRA、视频生成和其他管线与社区文档相同,见 [DiffSynth-Studio 文档中心](https://diffsynth-studio-doc.readthedocs.io/zh-cn/latest/)。 diff --git a/tests/diffsynth_studio/test_quick_start_ascend.py b/tests/diffsynth_studio/test_quick_start_ascend.py index 92db00538..1ee2a5955 100644 --- a/tests/diffsynth_studio/test_quick_start_ascend.py +++ b/tests/diffsynth_studio/test_quick_start_ascend.py @@ -62,8 +62,6 @@ def prepare_environment(cls) -> None: already ship ``LD_LIBRARY_PATH``, which would otherwise hide the CANN increment from ``set_env.sh``. """ - os.environ['PYTHONNOUSERSITE'] = '1' - if os.path.isfile(cls._CANN_SET_ENV): merged = subprocess.run( ['bash', '-c', f'source {cls._CANN_SET_ENV} >/dev/null 2>&1; env'], From 1cc3f4be29a780221c4faad066e1a40d64b79a17 Mon Sep 17 00:00:00 2001 From: lichuyang Date: Mon, 28 Sep 2026 14:39:19 +0800 Subject: [PATCH 3/9] =?UTF-8?q?docs(diffsynth):=20=E7=94=9F=E6=88=90?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=89=8D=E5=86=99=E6=98=8E=E7=94=A8=20python?= =?UTF-8?q?=20=E6=89=A7=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sources/diffsynth_studio/quick_start.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/diffsynth_studio/quick_start.md b/sources/diffsynth_studio/quick_start.md index cbb78b4f4..f41f0d3b7 100644 --- a/sources/diffsynth_studio/quick_start.md +++ b/sources/diffsynth_studio/quick_start.md @@ -114,7 +114,7 @@ device_name npu:0 ## 5. 在 NPU 上生成一张图 -用 Python 执行以下代码。种子为 42,推理 5 步,高和宽都是 512。权重从 Hugging Face 下载。 +用 Python 执行以下代码。种子为 42,推理 5 步,高和宽都是 512。权重从 Hugging Face 下载。用 python 执行以下代码: ```python #test id="generate" import torch From 21b91ff799f6f84a66f3744875a85c6e465a8f0e Mon Sep 17 00:00:00 2001 From: lichuyang Date: Wed, 30 Sep 2026 09:36:18 +0800 Subject: [PATCH 4/9] =?UTF-8?q?docs(diffsynth):=20=E6=8A=8A=E5=AE=89?= =?UTF-8?q?=E8=A3=85=E5=90=8E=E7=9A=84=E8=AE=BE=E5=A4=87=E8=BE=93=E5=87=BA?= =?UTF-8?q?=E5=B1=95=E7=A4=BA=E7=BB=99=E8=AF=BB=E8=80=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sources/diffsynth_studio/quick_start.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/sources/diffsynth_studio/quick_start.md b/sources/diffsynth_studio/quick_start.md index f41f0d3b7..9b0f37032 100644 --- a/sources/diffsynth_studio/quick_start.md +++ b/sources/diffsynth_studio/quick_start.md @@ -103,14 +103,12 @@ python -m pip install --retries 3 diffsynth python -c "import torch, torch_npu; from importlib.metadata import version; from diffsynth.core.device.npu_compatible_device import get_device_name, get_device_type; print('diffsynth', version('diffsynth')); print('device_type', get_device_type()); print('device_name', get_device_name())" ``` - ## 5. 在 NPU 上生成一张图 From 1c282cbf2af60186b8803ba59d29a297412041e3 Mon Sep 17 00:00:00 2001 From: lichuyang Date: Wed, 30 Sep 2026 11:41:45 +0800 Subject: [PATCH 5/9] =?UTF-8?q?docs(diffsynth):=20=E5=AE=89=E8=A3=85?= =?UTF-8?q?=E7=BB=93=E6=9E=9C=E5=89=8D=E8=A1=A5=E4=B8=8A=E8=BE=93=E5=87=BA?= =?UTF-8?q?=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sources/diffsynth_studio/quick_start.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sources/diffsynth_studio/quick_start.md b/sources/diffsynth_studio/quick_start.md index 9b0f37032..db47bacfb 100644 --- a/sources/diffsynth_studio/quick_start.md +++ b/sources/diffsynth_studio/quick_start.md @@ -103,6 +103,8 @@ python -m pip install --retries 3 diffsynth python -c "import torch, torch_npu; from importlib.metadata import version; from diffsynth.core.device.npu_compatible_device import get_device_name, get_device_type; print('diffsynth', version('diffsynth')); print('device_type', get_device_type()); print('device_name', get_device_name())" ``` +输出结果如下: + ```shell #test-result id="install-diffsynth" ... diffsynth ... From 243deff2fa05d012ad9f25edc23c982bac9cf44b Mon Sep 17 00:00:00 2001 From: lichuyang Date: Wed, 30 Sep 2026 11:48:49 +0800 Subject: [PATCH 6/9] =?UTF-8?q?docs(diffsynth):=20=E6=8C=89=E4=B8=8A?= =?UTF-8?q?=E6=B8=B8=E6=9C=80=E6=96=B0=20release=20=E7=9A=84=20=20?= =?UTF-8?q?=E5=AE=89=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sources/diffsynth_studio/quick_start.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/sources/diffsynth_studio/quick_start.md b/sources/diffsynth_studio/quick_start.md index db47bacfb..798460cb0 100644 --- a/sources/diffsynth_studio/quick_start.md +++ b/sources/diffsynth_studio/quick_start.md @@ -16,7 +16,7 @@ Atlas 800T / 900 A2 训练系列,Ascend 910B。本文示例为单卡。 | CANN | toolkit 与驱动已安装,并能 `source set_env.sh`。版本按 [昇腾软件配套清单](https://www.hiascend.com/developer/download/compatibility) 选择 | | Python | 落在官方配套表范围内,并满足 DiffSynth-Studio 下限。当前正式版要求 3.10.1 及以上 | | PyTorch | 安装官方当前推荐的 `torch` 与 `torch_npu`,CPU 轮子的版本号带 `+cpu`。见 [CANN 与 PyTorch 配套表](https://github.com/Ascend/pytorch/blob/master/COMPATIBILITY.md) 和 [PyTorch 安装包](https://www.hiascend.com/developer/software/ai-frameworks/pytorch/download) | -| DiffSynth-Studio | 从 PyPI 安装 `diffsynth` | +| DiffSynth-Studio | 安装上游最新 release。下文命令中的 `` 即该标签 | | 模型 | [stable-diffusion-v1-5/stable-diffusion-v1-5](https://huggingface.co/stable-diffusion-v1-5/stable-diffusion-v1-5) | 阅读本文前,请先按 [快速安装昇腾环境](https://ascend.github.io/docs/sources/ascend/quick_install.html) 准备好 CANN 与驱动。 @@ -96,10 +96,17 @@ npu_available True ## 4. 安装 DiffSynth-Studio -安装 PyPI 上的 `diffsynth`,并打印设备类型和设备名。 +检出上游最新 release 并安装,然后打印设备类型和设备名。`` 为这个 release 标签。 -```shell #test id="install-diffsynth" -python -m pip install --retries 3 diffsynth + + +```shell #test id="install-diffsynth" load="upstream_ref>>ref" +git clone --depth 1 --branch https://github.com/modelscope/DiffSynth-Studio.git +python -m pip install --retries 3 --no-build-isolation ./DiffSynth-Studio python -c "import torch, torch_npu; from importlib.metadata import version; from diffsynth.core.device.npu_compatible_device import get_device_name, get_device_type; print('diffsynth', version('diffsynth')); print('device_type', get_device_type()); print('device_name', get_device_name())" ``` From 3148e1961c2cdbe4c191ebf9e7042b2f04169861 Mon Sep 17 00:00:00 2001 From: lichuyang Date: Wed, 30 Sep 2026 11:51:09 +0800 Subject: [PATCH 7/9] =?UTF-8?q?docs(diffsynth):=20=E8=AF=B4=E6=98=8E?= =?UTF-8?q?=E5=B0=86=20=20=E6=8D=A2=E6=88=90=20PyPI=20=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sources/diffsynth_studio/quick_start.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sources/diffsynth_studio/quick_start.md b/sources/diffsynth_studio/quick_start.md index 798460cb0..71949f95d 100644 --- a/sources/diffsynth_studio/quick_start.md +++ b/sources/diffsynth_studio/quick_start.md @@ -16,7 +16,7 @@ Atlas 800T / 900 A2 训练系列,Ascend 910B。本文示例为单卡。 | CANN | toolkit 与驱动已安装,并能 `source set_env.sh`。版本按 [昇腾软件配套清单](https://www.hiascend.com/developer/download/compatibility) 选择 | | Python | 落在官方配套表范围内,并满足 DiffSynth-Studio 下限。当前正式版要求 3.10.1 及以上 | | PyTorch | 安装官方当前推荐的 `torch` 与 `torch_npu`,CPU 轮子的版本号带 `+cpu`。见 [CANN 与 PyTorch 配套表](https://github.com/Ascend/pytorch/blob/master/COMPATIBILITY.md) 和 [PyTorch 安装包](https://www.hiascend.com/developer/software/ai-frameworks/pytorch/download) | -| DiffSynth-Studio | 安装上游最新 release。下文命令中的 `` 即该标签 | +| DiffSynth-Studio | 当前正式版。将 `` 换成 PyPI 版本号,安装步骤见第 4 节 | | 模型 | [stable-diffusion-v1-5/stable-diffusion-v1-5](https://huggingface.co/stable-diffusion-v1-5/stable-diffusion-v1-5) | 阅读本文前,请先按 [快速安装昇腾环境](https://ascend.github.io/docs/sources/ascend/quick_install.html) 准备好 CANN 与驱动。 @@ -119,6 +119,10 @@ device_type npu device_name npu:0 ``` +```{note} +将 `` 换成 PyPI 版本号 +``` + ## 5. 在 NPU 上生成一张图 用 Python 执行以下代码。种子为 42,推理 5 步,高和宽都是 512。权重从 Hugging Face 下载。用 python 执行以下代码: From bc1ce24414e942928fd4c12eacf9bb2fde15f3d0 Mon Sep 17 00:00:00 2001 From: lichuyang Date: Wed, 30 Sep 2026 14:11:46 +0800 Subject: [PATCH 8/9] =?UTF-8?q?docs(diffsynth):=20=E6=8C=89=20PyPI=20?= =?UTF-8?q?=E6=AD=A3=E5=BC=8F=E7=89=88=E5=AE=89=E8=A3=85=EF=BC=8C=E9=81=BF?= =?UTF-8?q?=E5=85=8D=E6=A3=80=E5=87=BA=E6=97=A7=20release?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sources/diffsynth_studio/quick_start.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/sources/diffsynth_studio/quick_start.md b/sources/diffsynth_studio/quick_start.md index 71949f95d..dd95b97d1 100644 --- a/sources/diffsynth_studio/quick_start.md +++ b/sources/diffsynth_studio/quick_start.md @@ -96,17 +96,16 @@ npu_available True ## 4. 安装 DiffSynth-Studio -检出上游最新 release 并安装,然后打印设备类型和设备名。`` 为这个 release 标签。 +安装 `` 对应的 PyPI 正式版,然后打印设备类型和设备名。 ```shell #test id="install-diffsynth" load="upstream_ref>>ref" -git clone --depth 1 --branch https://github.com/modelscope/DiffSynth-Studio.git -python -m pip install --retries 3 --no-build-isolation ./DiffSynth-Studio +python -m pip install --retries 3 --no-build-isolation "diffsynth==" python -c "import torch, torch_npu; from importlib.metadata import version; from diffsynth.core.device.npu_compatible_device import get_device_name, get_device_type; print('diffsynth', version('diffsynth')); print('device_type', get_device_type()); print('device_name', get_device_name())" ``` @@ -120,7 +119,7 @@ device_name npu:0 ``` ```{note} -将 `` 换成 PyPI 版本号 +将 换成 最新的 release 版本号 ``` ## 5. 在 NPU 上生成一张图 From 608b50271abf55679b7b2d40668b16d04691723e Mon Sep 17 00:00:00 2001 From: lichuyang Date: Wed, 30 Sep 2026 16:20:58 +0800 Subject: [PATCH 9/9] =?UTF-8?q?docs(diffsynth):=20note=20=E9=87=8C?= =?UTF-8?q?=E7=94=A8=E4=BB=A3=E7=A0=81=E6=A0=87=E8=AE=B0=E6=A0=87=E5=87=BA?= =?UTF-8?q?=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sources/diffsynth_studio/quick_start.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/diffsynth_studio/quick_start.md b/sources/diffsynth_studio/quick_start.md index dd95b97d1..c0bff5089 100644 --- a/sources/diffsynth_studio/quick_start.md +++ b/sources/diffsynth_studio/quick_start.md @@ -119,7 +119,7 @@ device_name npu:0 ``` ```{note} -将 换成 最新的 release 版本号 +将 `` 换成 最新的 release 版本号 ``` ## 5. 在 NPU 上生成一张图