diff --git a/diffsynth/core/data/operators.py b/diffsynth/core/data/operators.py index 1b8d9a3..c14944e 100644 --- a/diffsynth/core/data/operators.py +++ b/diffsynth/core/data/operators.py @@ -3,7 +3,6 @@ import imageio.v3 as iio from PIL import Image - class DataProcessingPipeline: def __init__(self, operators=None): self.operators: list[DataProcessingOperator] = [] if operators is None else operators @@ -19,7 +18,6 @@ class DataProcessingPipeline: return DataProcessingPipeline(self.operators + pipe.operators) - class DataProcessingOperator: def __call__(self, data): raise NotImplementedError("DataProcessingOperator cannot be called directly.") @@ -30,25 +28,21 @@ class DataProcessingOperator: return DataProcessingPipeline([self]).__rshift__(pipe) - class DataProcessingOperatorRaw(DataProcessingOperator): def __call__(self, data): return data - class ToInt(DataProcessingOperator): def __call__(self, data): return int(data) - class ToFloat(DataProcessingOperator): def __call__(self, data): return float(data) - class ToStr(DataProcessingOperator): def __init__(self, none_value=""): self.none_value = none_value @@ -58,7 +52,6 @@ class ToStr(DataProcessingOperator): return str(data) - class LoadImage(DataProcessingOperator): def __init__(self, convert_RGB=True): self.convert_RGB = convert_RGB @@ -69,9 +62,8 @@ class LoadImage(DataProcessingOperator): return image - class ImageCropAndResize(DataProcessingOperator): - def __init__(self, height, width, max_pixels, height_division_factor, width_division_factor): + def __init__(self, height=None, width=None, max_pixels=None, height_division_factor=1, width_division_factor=1): self.height = height self.width = width self.max_pixels = max_pixels @@ -101,19 +93,16 @@ class ImageCropAndResize(DataProcessingOperator): height, width = self.height, self.width return height, width - def __call__(self, data: Image.Image): image = self.crop_and_resize(data, *self.get_height_width(data)) return image - class ToList(DataProcessingOperator): def __call__(self, data): return [data] - class LoadVideo(DataProcessingOperator): def __init__(self, num_frames=81, time_division_factor=4, time_division_remainder=1, frame_processor=lambda x: x): self.num_frames = num_frames @@ -143,7 +132,6 @@ class LoadVideo(DataProcessingOperator): return frames - class SequencialProcess(DataProcessingOperator): def __init__(self, operator=lambda x: x): self.operator = operator @@ -152,7 +140,6 @@ class SequencialProcess(DataProcessingOperator): return [self.operator(i) for i in data] - class LoadGIF(DataProcessingOperator): def __init__(self, num_frames=81, time_division_factor=4, time_division_remainder=1, frame_processor=lambda x: x): self.num_frames = num_frames @@ -181,7 +168,6 @@ class LoadGIF(DataProcessingOperator): if len(frames) >= num_frames: break return frames - class RouteByExtensionName(DataProcessingOperator): @@ -196,7 +182,6 @@ class RouteByExtensionName(DataProcessingOperator): raise ValueError(f"Unsupported file: {data}") - class RouteByType(DataProcessingOperator): def __init__(self, operator_map): self.operator_map = operator_map @@ -208,7 +193,6 @@ class RouteByType(DataProcessingOperator): raise ValueError(f"Unsupported data: {data}") - class LoadTorchPickle(DataProcessingOperator): def __init__(self, map_location="cpu"): self.map_location = map_location @@ -217,7 +201,6 @@ class LoadTorchPickle(DataProcessingOperator): return torch.load(data, map_location=self.map_location, weights_only=False) - class ToAbsolutePath(DataProcessingOperator): def __init__(self, base_path=""): self.base_path = base_path @@ -225,3 +208,11 @@ class ToAbsolutePath(DataProcessingOperator): def __call__(self, data): return os.path.join(self.base_path, data) + +class LoadAudio(DataProcessingOperator): + def __init__(self, sr=16000): + self.sr = sr + def __call__(self, data: str): + import librosa + input_audio, sample_rate = librosa.load(data, sr=self.sr) + return input_audio diff --git a/diffsynth/core/vram/layers.py b/diffsynth/core/vram/layers.py index cdfff0b..5ab9a3a 100644 --- a/diffsynth/core/vram/layers.py +++ b/diffsynth/core/vram/layers.py @@ -402,17 +402,3 @@ def enable_vram_management(model: torch.nn.Module, module_map: dict, vram_config # `vram_management_enabled` is a flag that allows the pipeline to determine whether VRAM management is enabled. model.vram_management_enabled = True return model - - -def reset_vram_config(model: torch.nn.Module, vram_config: dict, vram_limit=None): - disk_map = None - for module in model.modules(): - if isinstance(module, AutoTorchModule): - module.set_dtype_and_device(**vram_config, vram_limit=vram_limit) - if hasattr(module, "disk_map") and getattr(module, "disk_map") is not None: - disk_map = getattr(module, "disk_map") - if disk_map is not None: - devices = [vram_config["offload_device"], vram_config["onload_device"], vram_config["preparing_device"], vram_config["computation_device"]] - device = [d for d in devices if d != "disk"][0] - disk_map.device = device - disk_map.flush_files() diff --git a/docs/API_Reference/core/attention.md b/docs/API_Reference/core/attention.md index 1aed20a..919ff03 100644 --- a/docs/API_Reference/core/attention.md +++ b/docs/API_Reference/core/attention.md @@ -46,7 +46,7 @@ output_1 = attention(query, key, value) * xFormers:[GitHub](https://github.com/facebookresearch/xformers)、[文档](https://facebookresearch.github.io/xformers/components/ops.html#module-xformers.ops) * PyTorch:[GitHub](https://github.com/pytorch/pytorch)、[文档](https://docs.pytorch.org/docs/stable/generated/torch.nn.functional.scaled_dot_product_attention.html) -如需调用除 `PyTorch` 外的其他注意力实现,请按照其 GitHub 页面的指引安装对应的包。`DiffSynth-Studio` 会自动根据 Python 环境中的可用包路由到对应的实现上,也可通过[环境变量](../Environment_Variables.md#diffsynth_attention_implementation)控制。 +如需调用除 `PyTorch` 外的其他注意力实现,请按照其 GitHub 页面的指引安装对应的包。`DiffSynth-Studio` 会自动根据 Python 环境中的可用包路由到对应的实现上,也可通过[环境变量](/docs/Pipeline_Usage/Environment_Variables.md#diffsynth_attention_implementation)控制。 ```python from diffsynth.core.attention import attention_forward diff --git a/docs/API_Reference/core/data.md b/docs/API_Reference/core/data.md index 159b77d..713576f 100644 --- a/docs/API_Reference/core/data.md +++ b/docs/API_Reference/core/data.md @@ -1,3 +1,150 @@ -# `diffsynth.core.data`: 通用数据集与数据处理算子 +# `diffsynth.core.data`: 数据处理算子与通用数据集 +## 数据处理算子 +### 可用数据处理算子 + +`diffsynth.core.data` 提供了一系列数据处理算子,用于进行数据处理,包括: + +* 数据格式转换算子 + * `ToInt`: 转换为 int 格式 + * `ToFloat`: 转换为 float 格式 + * `ToStr`: 转换为 str 格式 + * `ToList`: 转换为列表格式,以列表包裹此数据 + * `ToAbsolutePath`: 将相对路径转换为绝对路径 +* 文件加载算子 + * `LoadImage`: 读取图片文件 + * `LoadVideo`: 读取视频文件 + * `LoadAudio`: 读取音频文件 + * `LoadGIF`: 读取 GIF 文件 + * `LoadTorchPickle`: 读取由 [`torch.save`](https://docs.pytorch.org/docs/stable/generated/torch.save.html) 保存的二进制文件【该算子可能导致二进制文件中的代码注入攻击,请谨慎使用!】 +* 媒体文件处理算子 + * `ImageCropAndResize`: 对图像进行裁剪和拉伸 +* Meta 算子 + * `SequencialProcess`: 将序列中的每个数据路由到一个算子 + * `RouteByExtensionName`: 按照文件扩展名路由到特定算子 + * `RouteByType`: 按照数据类型路由到特定算子 + +### 算子使用 + +数据算子之间以 `>>` 符号连接形成数据处理流水线,例如: + +```python +from diffsynth.core.data.operators import * + +data = "image.jpg" +data_pipeline = ToAbsolutePath(base_path="/data") >> LoadImage() >> ImageCropAndResize(max_pixels=512*512) +data = data_pipeline(data) +``` + +在经过每个算子后,数据被依次处理 + +* `ToAbsolutePath(base_path="/data")`: `"/data/image.jpg"` +* `LoadImage()`: `` +* `ImageCropAndResize(max_pixels=512*512)`: `` + +我们可以组合出功能完备的数据流水线,例如通用数据集的默认视频数据算子为 + +```python +RouteByType(operator_map=[ + (str, ToAbsolutePath(base_path) >> RouteByExtensionName(operator_map=[ + (("jpg", "jpeg", "png", "webp"), LoadImage() >> ImageCropAndResize(height, width, max_pixels, height_division_factor, width_division_factor) >> ToList()), + (("gif",), LoadGIF( + num_frames, time_division_factor, time_division_remainder, + frame_processor=ImageCropAndResize(height, width, max_pixels, height_division_factor, width_division_factor), + )), + (("mp4", "avi", "mov", "wmv", "mkv", "flv", "webm"), LoadVideo( + num_frames, time_division_factor, time_division_remainder, + frame_processor=ImageCropAndResize(height, width, max_pixels, height_division_factor, width_division_factor), + )), + ])), +]) +``` + +它包含如下逻辑: + +* 如果是 `str` 类型的数据 + * 如果是 `"jpg", "jpeg", "png", "webp"` 类型文件 + * 加载这张图片 + * 裁剪并缩放到特定分辨率 + * 打包进列表,视为单帧视频 + * 如果是 `"gif"` 类型文件 + * 加载 gif 文件内容 + * 将每一帧裁剪和缩放到特定分辨率 + * 如果是 `"mp4", "avi", "mov", "wmv", "mkv", "flv", "webm"` 类型文件 + * 加载 gif 文件内容 + * 将每一帧裁剪和缩放到特定分辨率 +* 如果不是 `str` 类型的数据,报错 + +## 通用数据集 + +`diffsynth.core.data` 提供了统一的数据集实现,数据集需输入以下参数: + +* `base_path`: 根目录,若数据集中包含图片文件的相对路径,则需填入此字段用于加载这些路径指向的文件 +* `metadata_path`: 元数据目录,记录所有元数据的文件路径,支持 `csv`、`json`、`jsonl` 格式 +* `repeat`: 数据重复次数,默认为 1,该参数影响一个 epoch 的训练步数 +* `data_file_keys`: 需进行加载的数据字段名,例如 `(image, edit_image)` +* `main_data_operator`: 主加载算子,需通过数据处理算子组装好数据处理流水线 +* `special_operator_map`: 特殊算子映射,对需要特殊处理的字段构建的算子映射 + +### 元数据 + +数据集的 `metadata_path` 指向元数据文件,支持 `csv`、`json`、`jsonl` 格式,以下提供了样例 + +* `csv` 格式:可读性高、不支持列表数据、内存占用小 + +```csv +image,prompt +image_1.jpg,"a dog" +image_2.jpg,"a cat" +``` +* `json` 格式:可读性高、支持列表数据、内存占用大 + +```json +[ + { + "image": "image_1.jpg", + "prompt": "a dog" + }, + { + "image": "image_2.jpg", + "prompt": "a cat" + } +] +``` + +* `jsonl` 格式:可读性低、支持列表数据、内存占用小 + +```json +{"image": "image_1.jpg", "prompt": "a dog"} +{"image": "image_2.jpg", "prompt": "a cat"} +``` + +如何选择最佳的元数据格式? + +* 如果数据量大,达到千万级的数据量,由于 `json` 文件解析时需要额外内存,此时不可用,请使用 `csv` 或 `jsonl` 格式 +* 如果数据集中包含列表数据,例如编辑模型需输入多张图,由于 `csv` 格式无法存储列表格式数据,此时不可用,请使用 `json` 或 `jsonl` 格式 + +### 数据加载逻辑 + +在没有进行额外设置时,数据集默认输出元数据集中的数据,图片和视频文件的路径会以字符串的格式输出,若要加载这些文件,则需要设置 `data_file_keys`、`main_data_operator`、`special_operator_map`。 + +在数据处理流程中,按如下逻辑进行处理: +* 如果字段位于 `special_operator_map`,则调用 `special_operator_map` 中的对应算子进行处理 +* 如果字段不位于 `special_operator_map` + * 如果字段位于 `data_file_keys`,则调用 `main_data_operator` 算子进行处理 + * 如果字段不位于 `data_file_keys`,则不进行处理 + +`special_operator_map` 可用于实现特殊的数据处理,例如模型 [Wan-AI/Wan2.2-Animate-14B](https://www.modelscope.cn/models/Wan-AI/Wan2.2-Animate-14B) 中输入的人物面部视频 `animate_face_video` 是以固定分辨率处理的,与输出视频不一致,因此这一字段由专门的算子处理: + +```python +special_operator_map={ + "animate_face_video": ToAbsolutePath(args.dataset_base_path) >> LoadVideo(args.num_frames, 4, 1, frame_processor=ImageCropAndResize(512, 512, None, 16, 16)), +} +``` + +### 其他注意事项 + +当数据量过少时,可适当增加 `repeat`,延长单个 epoch 的训练时间,避免频繁保存模型产生较多耗时。 + +当数据量 * `repeat` 超过 $10^9$ 时,我们观测到数据集的速度明显变慢,这似乎是 `PyTorch` 的 bug,我们尚不确定新版本的 `PyTorch` 是否已经修复了这一问题。 diff --git a/docs/API_Reference/core/gradient.md b/docs/API_Reference/core/gradient.md index 59dd29a..f92f6e8 100644 --- a/docs/API_Reference/core/gradient.md +++ b/docs/API_Reference/core/gradient.md @@ -1,4 +1,4 @@ -# `diffsynth.core.gradient`: 梯度检查点 +# `diffsynth.core.gradient`: 梯度检查点及其 Offload `diffsynth.core.gradient` 中提供了封装好的梯度检查点及其 Offload 版本,用于模型训练。 diff --git a/docs/API_Reference/core/loader.md b/docs/API_Reference/core/loader.md index e69de29..09e3ab1 100644 --- a/docs/API_Reference/core/loader.md +++ b/docs/API_Reference/core/loader.md @@ -0,0 +1,134 @@ +# `diffsynth.core.loader`: 模型下载与加载 + +本文档介绍 `diffsynth.core.loader` 中模型下载与加载相关的功能。 + +## ModelConfig + +`diffsynth.core.loader` 中的 `ModelConfig` 用于标注模型下载来源、本地路径、显存管理配置等信息。 + +### 从远程下载并加载模型 + +以模型[DiffSynth-Studio/Qwen-Image-Blockwise-ControlNet-Canny](https://www.modelscope.cn/models/DiffSynth-Studio/Qwen-Image-Blockwise-ControlNet-Canny) 为例,在 `ModelConfig` 中填写 `model_id` 和 `origin_file_pattern` 后即可自动下载模型。默认下载到 `./models` 路径,该路径可通过[环境变量 DIFFSYNTH_MODEL_BASE_PATH](/docs/Pipeline_Usage/Environment_Variables.md#diffsynth_model_base_path) 修改。 + +默认情况下,即使模型已经下载完毕,程序仍会向远程查询是否有遗漏文件,如果要完全关闭远程请求,请将[环境变量 DIFFSYNTH_SKIP_DOWNLOAD](/docs/Pipeline_Usage/Environment_Variables.md#diffsynth_skip_download) 设置为 `True`。 + +```python +from diffsynth.core import ModelConfig + +config = ModelConfig( + model_id="DiffSynth-Studio/Qwen-Image-Blockwise-ControlNet-Canny", + origin_file_pattern="model.safetensors", +) +# Download models +config.download_if_necessary() +``` + +### 从本地路径加载模型 + +如果从本地路径加载模型,则需要填入 `path`: + +```python +from diffsynth.core import ModelConfig + +config = ModelConfig(path="models/DiffSynth-Studio/Qwen-Image-Blockwise-ControlNet-Canny/model.safetensors") +``` + +如果模型包含多个分片文件,以列表的形式输入即可: + +```python +from diffsynth.core import ModelConfig + +config = ModelConfig(path=[ + "models/Qwen/Qwen-Image/text_encoder/model-00001-of-00004.safetensors", + "models/Qwen/Qwen-Image/text_encoder/model-00002-of-00004.safetensors", + "models/Qwen/Qwen-Image/text_encoder/model-00003-of-00004.safetensors", + "models/Qwen/Qwen-Image/text_encoder/model-00004-of-00004.safetensors" +]) +``` + +## 模型文件加载 + +`diffsynth.core.loader` 提供了统一的 `load_state_dict`,用于加载模型文件中的 state dict。 + +加载单个模型文件: + +```python +from diffsynth.core import load_state_dict + +state_dict = load_state_dict("models/DiffSynth-Studio/Qwen-Image-Blockwise-ControlNet-Canny/model.safetensors") +``` + +加载多个模型文件(合并为一个 state dict): + +```python +from diffsynth.core import load_state_dict + +state_dict = load_state_dict([ + "models/Qwen/Qwen-Image/text_encoder/model-00001-of-00004.safetensors", + "models/Qwen/Qwen-Image/text_encoder/model-00002-of-00004.safetensors", + "models/Qwen/Qwen-Image/text_encoder/model-00003-of-00004.safetensors", + "models/Qwen/Qwen-Image/text_encoder/model-00004-of-00004.safetensors" +]) +``` + +## 模型哈希 + +模型哈希是用于判断模型类型的,哈希值可通过 `hash_model_file` 获取: + +```python +from diffsynth.core import hash_model_file + +print(hash_model_file("models/DiffSynth-Studio/Qwen-Image-Blockwise-ControlNet-Canny/model.safetensors")) +``` + +也可计算多个模型文件的哈希值,等价于合并 state dict 后计算模型哈希值: + +```python +from diffsynth.core import hash_model_file + +print(hash_model_file([ + "models/Qwen/Qwen-Image/text_encoder/model-00001-of-00004.safetensors", + "models/Qwen/Qwen-Image/text_encoder/model-00002-of-00004.safetensors", + "models/Qwen/Qwen-Image/text_encoder/model-00003-of-00004.safetensors", + "models/Qwen/Qwen-Image/text_encoder/model-00004-of-00004.safetensors" +])) +``` + +模型哈希值只与模型文件中 state dict 的 keys 和 tensor shape 有关,与模型参数的数值、文件保存时间等信息无关。在计算 `.safetensors` 格式文件的模型哈希值时,`hash_model_file` 是几乎瞬间完成的,无需读取模型的参数;但在计算 `.bin`、`.pth`、`.ckpt` 等二进制文件的模型哈希值时,则需要读取全部模型参数,因此**我们不建议开发者继续使用这些格式的文件。** + +通过[编写模型 Config](/docs/Developer_Guide/Integrating_Your_Model.md#step-3-编写模型-config)并将模型哈希值等信息填入 `diffsynth/configs/model_configs.py`,开发者可以让 `DiffSynth-Studio` 自动识别模型类型并加载。 + +## 模型加载 + +`load_model` 是 `diffsynth.core.loader` 中加载模型的外部入口,它会调用 [skip_model_initialization](./vram.md#跳过模型参数初始化) 跳过模型参数初始化。如果启用了 [Disk Offload](/docs/Pipeline_Usage/VRAM_management.md#disk-offload),则调用 [DiskMap](./vram.md#state-dict-硬盘映射) 进行惰性加载;如果没有启用 Disk Offload,则调用 [load_state_dict](#模型文件加载) 加载模型参数。如果需要的话,还会调用 [state dict converter](/docs/Developer_Guide/Integrating_Your_Model.md#step-2-模型文件格式转换) 进行模型格式转换。最后调用 `model.eval()` 将其切换到推理模式。 + +以下是一个启用了 Disk Offload 的使用案例: + +```python +from diffsynth.core import load_model, enable_vram_management, AutoWrappedLinear, AutoWrappedModule +from diffsynth.models.qwen_image_dit import QwenImageDiT, RMSNorm +import torch + +prefix = "models/Qwen/Qwen-Image/transformer/diffusion_pytorch_model" +model_path = [prefix + f"-0000{i}-of-00009.safetensors" for i in range(1, 10)] + +model = load_model( + QwenImageDiT, + model_path, + module_map={ + torch.nn.Linear: AutoWrappedLinear, + RMSNorm: AutoWrappedModule, + }, + vram_config={ + "offload_dtype": "disk", + "offload_device": "disk", + "onload_dtype": "disk", + "onload_device": "disk", + "preparing_dtype": torch.bfloat16, + "preparing_device": "cuda", + "computation_dtype": torch.bfloat16, + "computation_device": "cuda", + }, + vram_limit=0, +) +``` diff --git a/docs/API_Reference/core/vram.md b/docs/API_Reference/core/vram.md index e69de29..4c9d7cd 100644 --- a/docs/API_Reference/core/vram.md +++ b/docs/API_Reference/core/vram.md @@ -0,0 +1,66 @@ +# `diffsynth.core.vram`: 显存管理 + +本文档介绍 `diffsynth.core.vram` 中的显存管理底层功能,如果你希望将这些功能用于其他的代码库中,可参考本文档。 + +## 跳过模型参数初始化 + +在 `PyTorch` 中加载模型时,模型的参数默认会占用显存或内存并进行参数初始化,而这些参数会在加载预训练权重后被覆盖掉,这导致了冗余的计算。`PyTorch` 中没有提供接口来跳过这些冗余的计算,我们在 `diffsynth.core.vram` 中提供了 `skip_model_initialization` 用于跳过模型参数初始化。 + +默认的模型加载方式: + +```python +from diffsynth.core import load_state_dict +from diffsynth.models.qwen_image_controlnet import QwenImageBlockWiseControlNet + +model = QwenImageBlockWiseControlNet() # Slow +path = "models/DiffSynth-Studio/Qwen-Image-Blockwise-ControlNet-Canny/model.safetensors" +state_dict = load_state_dict(path, device="cpu") +model.load_state_dict(state_dict, assign=True) +``` + +跳过参数初始化的模型加载方式: + +```python +from diffsynth.core import load_state_dict, skip_model_initialization +from diffsynth.models.qwen_image_controlnet import QwenImageBlockWiseControlNet + +with skip_model_initialization(): + model = QwenImageBlockWiseControlNet() # Fast +path = "models/DiffSynth-Studio/Qwen-Image-Blockwise-ControlNet-Canny/model.safetensors" +state_dict = load_state_dict(path, device="cpu") +model.load_state_dict(state_dict, assign=True) +``` + +在 `DiffSynth-Studio` 中,所有预训练模型都遵循这一加载逻辑。开发者在[接入模型](/docs/Developer_Guide/Integrating_Your_Model.md)完毕后即可直接以这种方式快速加载模型。 + +## State Dict 硬盘映射 + +对于某个模型的预训练权重文件,如果我们只需要读取其中的一组参数,而非全部参数,State Dict 硬盘映射可以加速这一过程。我们在 `diffsynth.core.vram` 中提供了 `DiskMap` 用于按需加载模型参数。 + +默认的权重加载方式: + +```python +from diffsynth.core import load_state_dict + +path = "models/DiffSynth-Studio/Qwen-Image-Blockwise-ControlNet-Canny/model.safetensors" +state_dict = load_state_dict(path, device="cpu") # Slow +print(state_dict["img_in.weight"]) +``` + +使用 `DiskMap` 只加载特定参数: + +```python +from diffsynth.core import DiskMap + +path = "models/DiffSynth-Studio/Qwen-Image-Blockwise-ControlNet-Canny/model.safetensors" +state_dict = DiskMap(path, device="cpu") # Fast +print(state_dict["img_in.weight"]) +``` + +`DiskMap` 是 `DiffSynth-Studio` 中 Disk Offload 的基本组件,开发者在[配置细粒度显存管理方案](/docs/Developer_Guide/Enabling_VRAM_management.md)后即可直接启用 Disk Offload。 + +`DiskMap` 是利用 `.safetensors` 文件的特性实现的功能,因此在使用 `.bin`、`.pth`、`.ckpt` 等二进制文件时,模型的参数是全量加载的,这也导致 Disk Offload 不支持这些格式的文件。**我们不建议开发者继续使用这些格式的文件。** + +## 显存管理可替换模块 + +在启用 `DiffSynth-Studio` 的显存管理后,模型内部的模块会被替换为 `diffsynth.core.vram.layers` 中的可替换模块,其使用方式详见[细粒度显存管理方案](/docs/Developer_Guide/Enabling_VRAM_management.md#编写细粒度显存管理方案)。 diff --git a/docs/Developer_Guide/Building_a_Pipeline.md b/docs/Developer_Guide/Building_a_Pipeline.md index 01e7715..b1a34d9 100644 --- a/docs/Developer_Guide/Building_a_Pipeline.md +++ b/docs/Developer_Guide/Building_a_Pipeline.md @@ -1,4 +1,4 @@ -# Pipeline 构建 +# 接入 Pipeline 在[将 Pipeline 所需的模型接入](./Integrating_Your_Model.md)之后,还需构建 `Pipeline` 用于模型推理,本文档提供 `Pipeline` 构建的标准化流程,开发者也可参考现有的 `Pipeline` 进行构建。 diff --git a/docs/Developer_Guide/Enabling_VRAM_management.md b/docs/Developer_Guide/Enabling_VRAM_management.md index 4389961..22ef752 100644 --- a/docs/Developer_Guide/Enabling_VRAM_management.md +++ b/docs/Developer_Guide/Enabling_VRAM_management.md @@ -1,4 +1,4 @@ -# 启用显存管理 +# 细粒度显存管理方案 本文档介绍如何为模型编写合理的细粒度显存管理方案,以及如何将 `DiffSynth-Studio` 中的显存管理功能用于外部的其他代码库,在阅读本文档前,请先阅读文档[显存管理](../Pipeline_Usage/VRAM_management.md)。 @@ -33,7 +33,7 @@ with torch.no_grad(): output = model(**inputs) ``` -## 细粒度显存管理方案 +## 编写细粒度显存管理方案 为了编写细粒度的显存管理方案,我们需用 `print(model)` 观察和分析模型结构: diff --git a/docs/Developer_Guide/Integrating_Your_Model.md b/docs/Developer_Guide/Integrating_Your_Model.md index f5d5a3c..dccb27f 100644 --- a/docs/Developer_Guide/Integrating_Your_Model.md +++ b/docs/Developer_Guide/Integrating_Your_Model.md @@ -1,4 +1,4 @@ -# 模型接入 +# 接入模型结构 本文档介绍如何将模型接入到 `DiffSynth-Studio` 框架中,供 `Pipeline` 等模块调用。 diff --git a/docs/Developer_Guide/Training_Diffusion_Models.md b/docs/Developer_Guide/Training_Diffusion_Models.md index 6c94c60..104d56d 100644 --- a/docs/Developer_Guide/Training_Diffusion_Models.md +++ b/docs/Developer_Guide/Training_Diffusion_Models.md @@ -1,4 +1,4 @@ -# 模型训练 +# 接入模型训练 在[接入模型](./Integrating_Your_Model.md)并[实现 Pipeline](./Building_a_Pipeline.md)后,接下来接入模型训练功能。 diff --git a/docs/Overview.md b/docs/Overview.md index e69de29..5daab7a 100644 --- a/docs/Overview.md +++ b/docs/Overview.md @@ -0,0 +1,41 @@ +# DiffSynth-Studio 文档 + +`DiffSynth-Studio` 旨在构建一个通用的 Diffusion 模型框架,支持主流 Diffusion 模型的推理和训练,孵化模型技术的创新成果。 + +## Section 1: 上手使用 + +本节介绍 `DiffSynth-Studio` 的基本使用方式,包括如何启用显存管理从而在极低显存的 GPU 上进行推理,以及如何训练任意基础模型、LoRA、ControlNet 等模型。 + +* [快速开始](./Pipeline_Usage/Quick_Start.md)【TODO】 +* [模型推理](./Pipeline_Usage/Model_Inference.md)【TODO】 +* [显存管理](./Pipeline_Usage/VRAM_management.md) +* [模型训练](./Pipeline_Usage/Model_Training.md)【TODO】 +* [环境变量](./Pipeline_Usage/Environment_Variables.md) + +## Section 2: 模型接入 + +本节介绍如何将模型接入 `DiffSynth-Studio` 从而使用框架基础功能,帮助开发者为本项目提供新模型的支持,或进行私有化模型的推理和训练。 + +* [接入模型结构](./Developer_Guide/Integrating_Your_Model.md) +* [接入 Pipeline](./Developer_Guide/Building_a_Pipeline.md) +* [接入细粒度显存管理](./Developer_Guide/Enabling_VRAM_management.md) +* [接入模型训练](./Developer_Guide/Training_Diffusion_Models.md) + +## Section 3: API 参考 + +本节介绍 `DiffSynth-Studio` 中的独立核心模块 `diffsynth.core`,介绍内部的功能是如何设计和运作的,开发者如有需要,可将其中的功能模块用于其他代码库的开发中。 + +* [`diffsynth.core.attention`](./API_Reference/core/attention.md): 注意力机制实现 +* [`diffsynth.core.data`](./API_Reference/core/data.md): 数据处理算子与通用数据集 +* [`diffsynth.core.gradient`](./API_Reference/core/gradient.md): 梯度检查点 +* [`diffsynth.core.loader`](./API_Reference/core/loader.md): 模型下载与加载 +* [`diffsynth.core.vram`](./API_Reference/core/vram.md): 显存管理 + +## Section 4: 学术导引 + +本节介绍如何利用 `DiffSynth-Studio` 训练新的模型,帮助科研工作者探索新的模型技术。 + +* 从零开始训练模型【TODO】 +* 推理改进优化技术【TODO】 +* 设计可控生成模型【TODO】 +* 创建新的训练范式【TODO】 diff --git a/docs/API_Reference/Environment_Variables.md b/docs/Pipeline_Usage/Environment_Variables.md similarity index 100% rename from docs/API_Reference/Environment_Variables.md rename to docs/Pipeline_Usage/Environment_Variables.md diff --git a/docs/Pipeline_Usage/Model_Inference.md b/docs/Pipeline_Usage/Model_Inference.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/Pipeline_Usage/Model_Training.md b/docs/Pipeline_Usage/Model_Training.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/Pipeline_Usage/Quick_Start.md b/docs/Pipeline_Usage/Quick_Start.md new file mode 100644 index 0000000..19aca66 --- /dev/null +++ b/docs/Pipeline_Usage/Quick_Start.md @@ -0,0 +1,28 @@ +# 快速开始 + +## 安装 + +从源码安装(推荐): + +``` +git clone https://github.com/modelscope/DiffSynth-Studio.git +cd DiffSynth-Studio +pip install -e . +``` + +
+其他安装方式 + +从 pypi 安装(存在版本更新延迟,如需使用最新功能,请从源码安装) + +``` +pip install diffsynth +``` + +如果在安装过程中遇到问题,可能是由上游依赖包导致的,请参考这些包的文档: + +* [torch](https://pytorch.org/get-started/locally/) +* [sentencepiece](https://github.com/google/sentencepiece) +* [cmake](https://cmake.org) + +