国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Stable Diffusion XL優(yōu)化終極指南

這篇具有很好參考價值的文章主要介紹了Stable Diffusion XL優(yōu)化終極指南。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

如何在自己的顯卡上獲得SDXL的最佳質(zhì)量和性能,以及如何選擇適當(dāng)?shù)膬?yōu)化方法和工具,這一讓GenAI用戶倍感困惑的問題,業(yè)內(nèi)一直沒有一份清晰而詳盡的評測報告可供參考。直到全棧開發(fā)者Félix San出手。

在本文中,F(xiàn)élix介紹了相關(guān)SDXL優(yōu)化的方法論、基礎(chǔ)優(yōu)化、Pipeline優(yōu)化以及組件和參數(shù)優(yōu)化。值得一提的是,基于實測表現(xiàn),他高度評價并推薦了由硅基流動研發(fā)的圖片/視頻推理加速引擎OneDiff,“I?just wanted to say that onediff is the fastest of them all! so great job!!(我只想說,OneDiff是所有圖像推理引擎中最快的!非常棒的工作?。。?/p>

由于本文內(nèi)容相當(dāng)扎實,篇幅相對較長,不過,他很貼心地提醒讀者,可以直接翻到末尾看結(jié)論。

感謝Félix出色的專業(yè)評測報告。關(guān)于Stable Diffusion XL優(yōu)化指南,讀這一篇就夠了。

(本文由OneFlow編譯發(fā)布,轉(zhuǎn)載請聯(lián)系授權(quán)。原文:https://www.felixsanz.dev/articles/ultimate-guide-to-optimizing-stable-diffusion-xl)

本文將介紹Stable Diffusion XL優(yōu)化,旨在盡可能減少內(nèi)存使用的同時實現(xiàn)最優(yōu)性能,從而加快圖像生成速度。我們將能夠僅用4GB內(nèi)存生成SDXL圖像,因此可以使用低端顯卡。

由于本文以腳本/開發(fā)為導(dǎo)向,因此將使用Hugging Face的diffusers庫。即便如此,了解不同的優(yōu)化技術(shù)及其相互作用將有助于我們在各種應(yīng)用中充分利用這些技術(shù),例如Automatic1111的Stable Diffusion webUI,尤其是ComfyUI。

本文可能顯得冗長而深奧,但你無需一次性閱讀完畢。我的目標(biāo)是讓讀者了解各種現(xiàn)存的優(yōu)化技術(shù),并教會你何時以及如何使用和組合它們,盡管其中一些技術(shù)本身就已經(jīng)有了實質(zhì)性的差異。

你也可以直接跳到結(jié)論部分,其中包括所有測試的總結(jié)表格,以及針對追求質(zhì)量、速度或內(nèi)存受限條件下運行推理時的建議。

作者 |?Félix San

OneFlow編譯

翻譯|宛子琳、楊婷

1

方法論

在測試中,我使用了RunPod平臺,在Secure Cloud上生成了一個GPU Pod,配備了RTX 3090顯卡。盡管Secure Cloud的費用略高于Community Cloud($0.44/h vs $0.29/h),但對于測試來說,它似乎更合適。

該實例生成于EU-CZ-1區(qū)域,擁有24GB的VRAM(GPU)、32 個vCPU(AMD EPYC 7H12)和125GB的RAM(CPU和RAM值并不重要)。至于模板,我使用RunPod PyTorch 2.1(runpod/pytorch:2.1.0-py3.10-cuda11.8.0-devel-ubuntu22.04),這是一個基礎(chǔ)模板,沒有其他額外內(nèi)容。因為我們將對其進(jìn)行更改,所以PyTorch的版本并不重要,但該模板提供了Ubuntu、Python 3.10CUDA 11.8作為標(biāo)準(zhǔn)配置。只需兩次點擊并等待30秒,我們就已經(jīng)準(zhǔn)備好所需的一切。

如果你要在本地運行模型,請確保已安裝Python 3.10和CUDA或等效平臺(本文將使用CUDA)。

所有測試都是在虛擬環(huán)境中進(jìn)行的:

創(chuàng)建虛擬環(huán)境

python -m venv .venv

激活虛擬環(huán)境

# Unix
source .venv/bin/activate
# Windows
.venv\Scripts\activate

安裝所需庫:

pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118
pip install transformers accelerate diffusers

測試包括生成4張圖片,并比較不同的優(yōu)化技術(shù),其中一些我相信你以前可能沒有見過。這些不同主題的圖像是使用stabilityai/stable-diffusion-xl-base-1.0模型生成的,僅使用一個正向提示和一個固定種子。其余參數(shù)將保持默認(rèn)值:無負(fù)向提示,1024x1024尺寸,CFG值為5,步數(shù)為50(采樣步數(shù))。

提示和種子

queue = []
# Photorealistic portrait (Portrait)
queue.extend([{
  'prompt': '3/4 shot, candid photograph of a beautiful 30 year old redhead woman with messy dark hair, peacefully sleeping in her bed, night, dark, light from window, dark shadows, masterpiece, uhd, moody',
  'seed': 877866765,
}])
# Creative interior image (Interior)
queue.extend([{
  'prompt': 'futuristic living room with big windows, brown sofas, coffee table, plants, cyberpunk city, concept art, earthy colors',
  'seed': 5567822456,
}])
# Macro photography (Macro)
queue.extend([{
  'prompt': 'macro shot of a bee collecting nectar from lavender flowers',
  'seed': 2257899453,
}])
# Rendered 3D image (3D)
queue.extend([{
  'prompt': '3d rendered isometric fiji island beach, 3d tile, polygon, cartoony, mobile game',
  'seed': 987867834,
}])

以下是默認(rèn)生成的圖像:

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

? ? ? ? ? ?<左右滑動查看更多圖片>

以下是對比測試的結(jié)果:

  • 圖像的感知質(zhì)量(希望我是位優(yōu)秀的評判者)。

  • 生成每張圖像所需的時間,以及總編譯時間(如果有的話)。

  • 使用的最大內(nèi)存量。

每項測試都運行了5,并使用平均值進(jìn)行比較。

時間測量采用了以下結(jié)構(gòu):

from time import perf_counter
# Import libraries
# import ...


# Define prompts
# queue = []
# queue.extend ...


for i, generation in enumerate(queue, start=1):
  # We start the counter
  image_start = perf_counter()


  # Generate and save image
  # ...


  # We stop the counter and save the result
  generation['total_time'] = perf_counter() - image_start


# Print the generation time of each image
images_totals = ', '.join(map(lambda generation: str(round(generation['total_time'], 1)), queue))
print('Image time:', images_totals)


# Print the average time
images_average = round(sum(generation['total_time'] for generation in queue) / len(queue), 1)
print('Average image time:', images_average)

為了找出所使用的最大內(nèi)存量,文件末尾包含以下語句:

max_memory = round(torch.cuda.max_memory_allocated(device='cuda') / 1000000000, 2)
print('Max. memory used:', max_memory, 'GB')

每個測試中包含的內(nèi)容都是所需的最小代碼。雖然每個測試都有自己的結(jié)構(gòu),但代碼大致如下。

# Load the model on the graphics card
pipe = AutoPipelineForText2Image.from_pretrained(
  'stabilityai/stable-diffusion-xl-base-1.0',
  use_safetensors=True,
  torch_dtype=torch.float16,
  variant='fp16',
).to('cuda')


# Create a generator
generator = torch.Generator(device='cuda')


# Start a loop to process prompts one by one
for i, generation in enumerate(queue, start=1):
  # Assign the seed to the generator
  generator.manual_seed(generation['seed'])


  # Create the image
  image = pipe(
    prompt=generation['prompt'],
    generator=generator,
  ).images[0]


  # Save the image
  image.save(f'image_{i}.png')

為了使測試更真實且減少耗時,所有測試都將使用FP16優(yōu)化。

其中許多測試使用了diffusers庫中的pipeline,以便抽象復(fù)雜性并使代碼更清晰簡潔。當(dāng)測試需要時,抽象級別會降低,但最終我們一直會使用該庫提供的方法。另外,模型始終以safetensors格式加載,使用use_safetensors=True屬性。

文章中顯示的圖像尺寸最大為512x512,以便瀏覽,但你可以在新標(biāo)簽頁/窗口中打開圖像,查看其原始大小。

你可以在GitHub上的文章存儲庫(github.com/felixsanz/felixsanz_dev)中找到所有單獨的測試文件。

讓我們開始吧!

2

基本優(yōu)化

CUDA和PyTorch版本

我進(jìn)行該測試是想知道使用CUDA 11.8CUDA 12.1之間是否存在差異,以及在不同版本的PyTorch(始終在2.0以上)之間可能存在的差異。

測試結(jié)果:

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

結(jié)論:

真令人失望,它們的性能沒什么區(qū)別。差異是如此之小,也許如果我做更多的測試,這一差異可能會消失。

何時使用:關(guān)于該使用哪個版本,我仍然有一個理論:CUDA版本11.8發(fā)布的時間更長,理論上講,該版本的庫和應(yīng)用程序性能會優(yōu)于更新的版本。另一方面,對于PyTorch而言,版本越新,它應(yīng)該提供的功能也就越多,包含的bug也就越少。因此,即使只是心理作用,我也會堅持選擇CUDA 11.8 + PyTorch 2.2.0。

注意力機(jī)制

過去,注意機(jī)制必須通過安裝xFormers或FlashAttention等庫來進(jìn)行優(yōu)化。

如果你好奇為什么本文沒有提及上述優(yōu)化,那是因為已無必要。自PyTorch 2.0發(fā)布以來,通過各種實現(xiàn)(如上文中提到的這兩種),以上算法的優(yōu)化已經(jīng)被集成到庫里面。PyTorch會根據(jù)輸入和正在使用的硬件進(jìn)行適當(dāng)?shù)膶崿F(xiàn)。

FP16

默認(rèn)情況下,Stable Diffusion XL使用32 bit浮點格式(FP32)來表示其所處理和執(zhí)行計算的數(shù)字。

一個顯而易見的問題:能否降低精度?答案是肯定的。通過使用參數(shù)torch_dtype=torch.float16,模型會以半精度浮點格式(FP16)加載到內(nèi)存中。為了避免不斷進(jìn)行這種轉(zhuǎn)換,我們可以直接下載以FP16格式分發(fā)的模型變體。只需包括variant='fp16'參數(shù)即可。

pipe = AutoPipelineForText2Image.from_pretrained(
  'stabilityai/stable-diffusion-xl-base-1.0',
  use_safetensors=True,
  torch_dtype=torch.float16,
  variant='fp16',
).to('cuda')


generator = torch.Generator(device='cuda')


for i, generation in enumerate(queue, start=1):
  generator.manual_seed(generation['seed'])


  image = pipe(
    prompt=generation['prompt'],
    generator=generator,
  ).images[0]


  image.save(f'image_{i}.png')

測試結(jié)果:

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

? ?<左右滑動查看更多圖片>

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

結(jié)論:

通過使用半精度的數(shù)字,內(nèi)存占用大幅降低,計算速度也顯著提高。

唯一的“不足”是生成圖像質(zhì)量的降低,但實際上幾乎不可能看到任何區(qū)別,因為FP16足夠了。

此外,多虧了variant='fp16' 參數(shù),我們節(jié)省了磁盤空間,因為該變體占用的空間只有原來的一半(5GB 而不是 10GB)。

何時使用:隨時可用。

TF32

TensorFloat-32是介于FP32和FP16之間的一種格式,以使一些NVIDIA顯卡(如A100或H100)來使用張量核心執(zhí)行計算。它使用與FP32相同的bit來表示指數(shù),使用與FP16相同的bit來表示小數(shù)部分。

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

盡管在我們的測試平臺(RTX 3090)中無法使用此格式進(jìn)行計算,但出乎意料的是,有一些十分奇特的事發(fā)生。

有兩個屬性用于激活此數(shù)字格式:torch.backends.cudnn.allow_tf32(默認(rèn)情況下已激活)和torch.backends.cuda.matmul.allow_tf32(應(yīng)手動激活)。第一個屬性啟用了由cuDNN執(zhí)行的卷積操作中的TF32,而第二個屬性則啟用了矩陣乘法操作中的TF32。

torch.backends.cudnn.allow_tf32屬性默認(rèn)啟用,與你的顯卡是什么無關(guān),這樣的設(shè)定有點奇怪。如果我們將該屬性禁用,對其賦值False ,讓我們看看會發(fā)生什么。

torch.backends.cudnn.allow_tf32 = False
# it's already disabled by default
# torch.backends.cuda.matmul.allow_tf32 = False


pipe = AutoPipelineForText2Image.from_pretrained(
  'stabilityai/stable-diffusion-xl-base-1.0',
  use_safetensors=True,
  torch_dtype=torch.float16,
  variant='fp16',
).to('cuda')


generator = torch.Generator(device='cuda')


for i, generation in enumerate(queue, start=1):
  generator.manual_seed(generation['seed'])


  image = pipe(
    prompt=generation['prompt'],
    generator=generator,
  ).images[0]


  image.save(f'image_{i}.png')

另外,出于好奇,我還使用啟用了TF32的NVIDIA A100顯卡進(jìn)行了測試。

# it's already activated by default
# torch.backends.cudnn.allow_tf32 = True
torch.backends.cuda.matmul.allow_tf32 = True


pipe = AutoPipelineForText2Image.from_pretrained(
  'stabilityai/stable-diffusion-xl-base-1.0',
  use_safetensors=True,
).to('cuda')


generator = torch.Generator(device='cuda')


for i, generation in enumerate(queue, start=1):
  generator.manual_seed(generation['seed'])


  image = pipe(
    prompt=generation['prompt'],
    generator=generator,
  ).images[0]


  image.save(f'image_{i}.png')

權(quán)衡:要使用TF32,必須禁用FP16格式,因此我們無法使用 torch_dtype=torch.float16 或 ?variant='fp16' 。

測試結(jié)果:

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

結(jié)論

在使用RTX 3090 時,如果禁用 torch.backends.cudnn.allow_tf32 屬性,內(nèi)存占用會減少 7%。為什么呢?我不知道,原則上講,我認(rèn)為這可能是一個 bug,因為在不支持TF32的顯卡上啟用TF32毫無意義。

使用A100顯卡時,使用FP16能夠顯著減少推理時間和內(nèi)存占用。就像在RTX 3090上一樣,通過禁用torch.backends.cudnn.allow_tf32屬性能夠進(jìn)一步減少內(nèi)存占用。至于使用TF32,則介于FP32和FP16之間,它無法超越 FP16。

何時使用:對于不支持TF32的顯卡,明智的選擇顯然是禁用默認(rèn)啟用的屬性。在使用A100時,如果可以使用FP16,就不值得使用TF32。

3

Pipeline優(yōu)化

以下優(yōu)化方法改進(jìn)了pipeline以改善某些方面的性能。

前三個優(yōu)化改進(jìn)了何時將Stable Diffusion的不同組件加載到內(nèi)存中,以便它們不會同時加載。以上技術(shù)實現(xiàn)了減少內(nèi)存使用量的目的。

當(dāng)由于顯卡和內(nèi)存限制而需要這些優(yōu)化時,請使用這些優(yōu)化方法。如果在Linux上收到RuntimeError: CUDA out of memory報錯,本節(jié)內(nèi)容就是你所需要的。在Windows上,默認(rèn)情況下存在虛擬內(nèi)存(共享GPU內(nèi)存),盡管很難出現(xiàn)這種報錯,但推理時間會呈指數(shù)級增長,因此本節(jié)也是你需要關(guān)注的內(nèi)容。

至于本節(jié)中的最后三個優(yōu)化方法,它們以不同方式優(yōu)化pipeline的庫,以盡可能減少推理時間。

Model CPU Offload

Model CPU Offload優(yōu)化方法來自 accelerate 庫。當(dāng)執(zhí)行pipeline時,所有模型都會加載到內(nèi)存中。通過這一優(yōu)化,我們讓pipeline每次只在需要時將模型移入內(nèi)存。在pipeline的源代碼(https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/stable_diffusion_xl/pipeline_stable_diffusion_xl.py#L201)中可以找到這個順序,在Stable Diffusion XL的情況下,我們會找到以下代碼:

model_cpu_offload_seq = "text_encoder->text_encoder_2->image_encoder->unet->vae"

實現(xiàn)Model CPU Offload的代碼非常簡單:

pipe = AutoPipelineForText2Image.from_pretrained(
  'stabilityai/stable-diffusion-xl-base-1.0',
  use_safetensors=True,
  torch_dtype=torch.float16,
  variant='fp16',
).to('cuda')
pipe.enable_model_cpu_offload()
generator = torch.Generator(device='cuda')
for i, generation in enumerate(queue, start=1):
  generator.manual_seed(generation['seed'])
  image = pipe(
    prompt=generation['prompt'],
    generator=generator,
  ).images[0]
  image.save(f'image_{i}.png')

重要提醒:與其他優(yōu)化不同,我們不應(yīng)該使用 to('cuda')?將pipeline移至顯卡上。當(dāng)必要時,該優(yōu)化會進(jìn)行自動處理。(感謝Terrence Goh的提醒)

pipe = AutoPipelineForText2Image.from_pretrained(
  # ...
).to('cuda')

測試結(jié)果:

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

結(jié)論:

使用這一技術(shù)將取決于我們擁有的顯卡。如果顯卡有6-8GB內(nèi)存,這種優(yōu)化將有所幫助,因為內(nèi)存使用量正好減少了一半。

至于推理時間,不會受到太大影響以至于成為一個問題。

何時使用:需要減少內(nèi)存消耗時使用。由于消耗最多內(nèi)存的組件是噪聲預(yù)測器(U-Net),我們無法通過應(yīng)用優(yōu)化到VAE來進(jìn)一步減少內(nèi)存消耗。

Sequential CPU Offload

這種優(yōu)化與Model CPU Offload類似,只是更加激進(jìn)。它不是將整個組件移入內(nèi)存,而是將每個組件的子模塊移入內(nèi)存。例如,該優(yōu)化不是將整個U-Net模型移入內(nèi)存,而是在使用時移動特定部分,以盡可能少地占用內(nèi)存。這意味著,如果噪聲預(yù)測器必須在50步內(nèi)清理一個張量,那么子模塊必須進(jìn)出內(nèi)存50次。

同樣只需添加一行代碼:

pipe = AutoPipelineForText2Image.from_pretrained(
  'stabilityai/stable-diffusion-xl-base-1.0',
  use_safetensors=True,
  torch_dtype=torch.float16,
  variant='fp16',
)


pipe.enable_sequential_cpu_offload()


generator = torch.Generator(device='cuda')


for i, generation in enumerate(queue, start=1):
  generator.manual_seed(generation['seed'])


  image = pipe(
    prompt=generation['prompt'],
    generator=generator,
  ).images[0]


  image.save(f'image_{i}.png')

重要提示:使用模型CPU卸載時,記得不要在pipeline中使用 to('cuda')。

測試結(jié)果:

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

結(jié)論:

該優(yōu)化會考驗我們的耐心。為了盡可能減少內(nèi)存使用,推理時間會大幅增加。

何時使用:如果你需要不超過4GB的內(nèi)存,那么將該優(yōu)化與VAE FP16 fix或Tiny VAE一起使用是你的唯一選擇,但如果你不需要這么做,那再好不過。

批處理

該技術(shù)是從文章“How to implement Stable Diffusion(https://www.felixsanz.dev/articles/how-to-implement-stable-diffusion)”和“PixArt-α with less than 8GB VRAM(https://www.felixsanz.dev/articles/pixart-a-with-less-than-8gb-vram)”中獲取的學(xué)習(xí)成果,我才了解到這一技術(shù)。通過這些文章,你會找到一些我將使用但不再解釋的部分代碼信息。

這有關(guān)批處理中的執(zhí)行組件。其背后的理念與“Model CPU Offload”技術(shù)類似,問題在于官方pipeline實現(xiàn)并未最大程度地優(yōu)化內(nèi)存使用。當(dāng)你啟動pipeline,只想獲取文本編碼器時卻做不到。

也就是說,我們應(yīng)該能夠這樣做:

pipe = AutoPipelineForText2Image.from_pretrained(
  'stabilityai/stable-diffusion-xl-base-1.0',
  use_safetensors=True,
  torch_dtype=torch.float16,
  variant='fp16',
  unet=None,
  vae=None,
).to('cuda')

但實際上卻不能這樣做。當(dāng)你啟動pipeline時,它需要訪問U-Net模型配置 (self.unet.config.*),以及VAE配置 (self.vae.config.*)。

因此(并且無需創(chuàng)建分支),我們將手動使用文本編碼器,而不依賴于pipeline。

第一步是復(fù)制pipeline中的encode_prompt函數(shù),并對其進(jìn)行調(diào)整/簡化。

該函數(shù)負(fù)責(zé)對提示進(jìn)行詞元化并處理,以獲取已轉(zhuǎn)換的嵌入張量。你可以在“How to implement Stable Diffusion”中找到對這一過程的解釋。

def encode_prompt(prompts, tokenizers, text_encoders):
  embeddings_list = []
  for prompt, tokenizer, text_encoder in zip(prompts, tokenizers, text_encoders):
    cond_input = tokenizer(
      prompt,
      max_length=tokenizer.model_max_length,
      padding='max_length',
      truncation=True,
      return_tensors='pt',
    )
    prompt_embeds = text_encoder(cond_input.input_ids.to('cuda'), output_hidden_states=True)
    pooled_prompt_embeds = prompt_embeds[0]
    embeddings_list.append(prompt_embeds.hidden_states[-2])
  prompt_embeds = torch.concat(embeddings_list, dim=-1)
  negative_prompt_embeds = torch.zeros_like(prompt_embeds)
  negative_pooled_prompt_embeds = torch.zeros_like(pooled_prompt_embeds)
  bs_embed, seq_len, _ = prompt_embeds.shape
  prompt_embeds = prompt_embeds.repeat(1, 1, 1)
  prompt_embeds = prompt_embeds.view(bs_embed * 1, seq_len, -1)
  seq_len = negative_prompt_embeds.shape[1]
  negative_prompt_embeds = negative_prompt_embeds.repeat(1, 1, 1)
  negative_prompt_embeds = negative_prompt_embeds.view(1 * 1, seq_len, -1)
  pooled_prompt_embeds = pooled_prompt_embeds.repeat(1, 1).view(bs_embed * 1, -1)
  negative_pooled_prompt_embeds = negative_pooled_prompt_embeds.repeat(1, 1).view(bs_embed * 1, -1)
  return prompt_embeds, negative_prompt_embeds, pooled_prompt_embeds, negative_pooled_prompt_embeds

接下來,我們實例化所需的所有組件和模型。我們還需要垃圾收集器 (gc)。

import gc
from transformers import CLIPTokenizer, CLIPTextModel, CLIPTextModelWithProjection
# ...
tokenizer = CLIPTokenizer.from_pretrained(
  'stabilityai/stable-diffusion-xl-base-1.0',
  subfolder='tokenizer',
)
text_encoder = CLIPTextModel.from_pretrained(
  'stabilityai/stable-diffusion-xl-base-1.0',
  subfolder='text_encoder',
  use_safetensors=True,
  torch_dtype=torch.float16,
  variant='fp16',
).to('cuda')
tokenizer_2 = CLIPTokenizer.from_pretrained(
  'stabilityai/stable-diffusion-xl-base-1.0',
  subfolder='tokenizer_2',
)
text_encoder_2 = CLIPTextModelWithProjection.from_pretrained(
  'stabilityai/stable-diffusion-xl-base-1.0',
  subfolder='text_encoder_2',
  use_safetensors=True,
  torch_dtype=torch.float16,
  variant='fp16',
).to('cuda')

現(xiàn)在我們需要把這兩部分組合起來。我們調(diào)用encode_prompt函數(shù),并將相同的提示傳遞給第一個文本編碼器和第二個文本編碼器,并為其傳遞組件以供使用。

with torch.no_grad():
  for generation in queue:
    generation['embeddings'] = encode_prompt(
      [generation['prompt'], generation['prompt']],
      [tokenizer, tokenizer_2],
      [text_encoder, text_encoder_2],
    )

得到的張量作為結(jié)果存儲在變量中以供后續(xù)使用。

由于我們已經(jīng)處理了所有提示,可以從內(nèi)存中刪除這些組件:

del tokenizer, text_encoder, tokenizer_2, text_encoder_2
gc.collect()
torch.cuda.empty_cache()

現(xiàn)在,讓我們創(chuàng)建一個只能訪問U-Net和VAE的pipeline,無需實例化文本編碼器來節(jié)省內(nèi)存。

pipe = AutoPipelineForText2Image.from_pretrained(
  'stabilityai/stable-diffusion-xl-base-1.0',
  use_safetensors=True,
  torch_dtype=torch.float16,
  variant='fp16',
  tokenizer=None,
  text_encoder=None,
  tokenizer_2=None,
  text_encoder_2=None,
).to('cuda')

預(yù)熱:由于每個部分都是分開的,這個測試的預(yù)熱有點復(fù)雜。盡管如此,我們將使用以下代碼來預(yù)熱U-Net模型:

for generation in queue:
  pipe(
    prompt_embeds=generation['embeddings'][0],
    negative_prompt_embeds =generation['embeddings'][1],
    pooled_prompt_embeds=generation['embeddings'][2],
    negative_pooled_prompt_embeds=generation['embeddings'][3],
    output_type='latent',
  )

我們使用pipeline來處理上一步保存的嵌入張量。請記住,在這一部分中,pipeline創(chuàng)建了一個充滿噪音的張量,并在50步中對其進(jìn)行清理(同時受到我們的嵌入向量的引導(dǎo))。

generator = torch.Generator(device='cuda')


for i, generation in enumerate(queue, start=1):
  generator.manual_seed(generation['seed'])


  generation['latents'] = pipe(
    prompt_embeds=generation['embeddings'][0],
    negative_prompt_embeds =generation['embeddings'][1],
    pooled_prompt_embeds=generation['embeddings'][2],
    negative_pooled_prompt_embeds=generation['embeddings'][3],
    generator=generator,
    output_type='latent',
  ).images # We do not access images[0], but the entire tensor

正如你所見,我們指示pipeline返回潛在空間中的張量(output_type='latent')。如果不這樣做,VAE將被加載到內(nèi)存中以返回圖像,這將導(dǎo)致兩個模型同時占用資源。所以,就像我們之前刪除文本編碼器一樣,我們先刪除U-Net模型。

del pipe.unet
gc.collect()
torch.cuda.empty_cache()

現(xiàn)在,我們將存儲的無噪聲張量轉(zhuǎn)換為圖像:

pipe.upcast_vae()


with torch.no_grad():
  for i, generation in enumerate(queue, start=1):
    generation['latents'] = generation['latents'].to(next(iter(pipe.vae.post_quant_conv.parameters())).dtype)


    image = pipe.vae.decode(
      generation['latents'] / pipe.vae.config.scaling_factor,
      return_dict=False,
    )[0]


    image = pipe.image_processor.postprocess(image, output_type='pil')[0]
    image.save(f'image_{i}.png')

VAE(FP32):在Stable Diffusion XL中,我們用pipe.upcast_vae()來保持VAE為FP32格式,因為在FP16下它無法正常工作。

此循環(huán)負(fù)責(zé)將處于潛在空間的張量解碼,以將其轉(zhuǎn)換為圖像空間。然后,使用 pipe.image_processor.postprocess方法,將其轉(zhuǎn)換為圖像并保存。

測試結(jié)果:

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

結(jié)論:

這是我決定撰寫這篇文章的原因之一。推理時間沒有受到影響的情況下,我們將內(nèi)存占用減少了一半?,F(xiàn)在,甚至可以使用一張只有6GB內(nèi)存的顯卡來生成圖像。

何時使用:雖然Model CPU Offload只是多了一行代碼,但推理時間有所增加。因此,如果你不介意寫更多的代碼,使用這種技術(shù),你將擁有絕對的控制權(quán),并獲得更好的性能。你還可以使用專家去噪器集成(Ensemble of Expert Denoisers)方法添加精煉模型,而內(nèi)存消耗將保持不變。

Stable Fast

Stable Fast項目能夠通過一系列技術(shù)來加速任何擴(kuò)散模型(如使用增強(qiáng)版本的torch.jit.trace 進(jìn)行跟蹤模型、xFormers、高級的Channels-last-memory-format實現(xiàn)等)。事實上,他們做得非常出色。

他們承諾的結(jié)果是創(chuàng)下推理時間的記錄,遠(yuǎn)遠(yuǎn)超過torch.compile API,并趕上TensorRT。最有趣的是,由于這些是運行時優(yōu)化,就無需等待數(shù)十分鐘進(jìn)行初始編譯。

要集成Stable Fast,首先需要安裝項目庫,還有Triton,以及與我們正在使用的PyTorch版本兼容的xFormers版本。

pip install stable-fast
pip install torch torchvision triton xformers --index-url https://download.pytorch.org/whl/cu118

然后,利用Stable Fast修改腳本以導(dǎo)入并啟用這些庫:

import xformers
import triton
from sfast.compilers.diffusion_pipeline_compiler import (compile, CompilationConfig)


# ...


pipe = AutoPipelineForText2Image.from_pretrained(
  'stabilityai/stable-diffusion-xl-base-1.0',
  use_safetensors=True,
  torch_dtype=torch.float16,
  variant='fp16',
).to('cuda')


config = CompilationConfig.Default()


config.enable_xformers = True
config.enable_triton = True
config.enable_cuda_graph = True


pipe = compile(pipe, config)


generator = torch.Generator(device='cuda')


for i, generation in enumerate(queue, start=1):
  generator.manual_seed(generation['seed'])


  image = pipe(
    prompt=generation['prompt'],
    generator=generator,
  ).images[0]


  image.save(f'image_{i}.png')

此外,該項目還因其簡易性而脫穎而出,只需幾行代碼就能運行。現(xiàn)在讓我們看看它是否符合期望。

測試結(jié)果:

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

?<左右滑動查看更多圖片>

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

結(jié)論:

它超出了期望值。你可以看到該項目背后的出色工作。

最引人注目的是速度的提高。我們生成的第一張圖像需要較長時間(19秒),但如果在這些測試中進(jìn)行了預(yù)熱,就不重要了。

內(nèi)存使用量有所增加,但仍然相當(dāng)可控。

至于視覺效果,構(gòu)圖略有變化。在某些圖像中,某些元素的質(zhì)量甚至已經(jīng)提高,所以……眼見為實。

何時使用:我想說,隨時都可用。

DeepCache

DeepCache項目稱,要成為用戶可以實施的最佳優(yōu)化方法之一,幾乎沒有什么缺點,且易于添加。它利用緩存系統(tǒng)來重用高級別函數(shù),并以更高效的方式更新低級別函數(shù)。

首先,我們安裝所需的庫:

pip install deepcache

然后,我們將以下代碼集成到我們的pipeline中:

from DeepCache import DeepCacheSDHelper


# ...


pipe = AutoPipelineForText2Image.from_pretrained(
  'stabilityai/stable-diffusion-xl-base-1.0',
  use_safetensors=True,
  torch_dtype=torch.float16,
  variant='fp16',
).to('cuda')


helper = DeepCacheSDHelper(pipe=pipe)
helper.set_params(cache_interval=3, cache_branch_id=0)
helper.enable()


generator = torch.Generator(device='cuda')


for i, generation in enumerate(queue, start=1):
  generator.manual_seed(generation['seed'])


  image = pipe(
    prompt=generation['prompt'],
    generator=generator,
  ).images[0]


  image.save(f'image_{i}.png')

有兩個參數(shù)可以修改,以實現(xiàn)更高的速度,盡管會在結(jié)果中引入更大的質(zhì)量損失。

cache_interval=3:指定緩存在幾個步數(shù)后更新一次。

cache_branch_id=0:指定神經(jīng)網(wǎng)絡(luò)負(fù)責(zé)執(zhí)行緩存過程的分支(按降序排列,0 是第一層)。

讓我們看看使用默認(rèn)推薦參數(shù)的結(jié)果。

測試結(jié)果:

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

?<左右滑動查看更多圖片>

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

結(jié)論:

哇!在略微犧牲內(nèi)存使用量的情況下,推理時間可以減少一半以上。

至于圖像質(zhì)量,你可能已經(jīng)注意到變化很大,且不幸的是,變得更糟了。根據(jù)圖像的風(fēng)格,這一點可能更重要或不那么重要,但這個劣勢的確存在(在物體圖像中似乎并沒有太大影響)。

增加cache_branch_id的值似乎可以提供更高的視覺質(zhì)量,盡管可能還不夠。

何時使用:由于DeepCache大幅降低了推理時間,理所當(dāng)然地會稍微降低圖像質(zhì)量。毫無疑問,當(dāng)用于測試提示或參數(shù)時,這是一個非常有用的優(yōu)化方法,不過,當(dāng)你希望輸出更好的圖像質(zhì)量時就不適用了。

TensorRT

TensorRT是NVIDIA推出的高性能推理優(yōu)化器和運行時環(huán)境,旨在加速神經(jīng)網(wǎng)絡(luò)推理過程。

但我們從一開始就遇到了問題。我們的測試使用的是diffusers庫中的pipeline,目前還沒有與Stable Diffusion XL兼容的TensorRT pipeline。針對Stable Diffusion 2.x(txt2img、img2img 或 inpainting)有社區(qū)提供的pipeline。我也看到一些針對Stable Diffusion 1.x的pipeline,但正如我所說的,都不適用于SDXL。

另一方面,在HuggingFace上,我們可以找到官方的stabilityai/stable-diffusion-xl-1.0-tensorrt庫。其中包含了使用TensorRT執(zhí)行推理過程的說明,但不幸的是,它使用的腳本非常復(fù)雜,幾乎不可能適應(yīng)我們的測試。

由于使用的腳本甚至沒有相同的調(diào)度器(Euler),因此結(jié)果看起來會有很大不同。盡管如此,我盡可能地重用了許多數(shù)值,包括正向提示、無負(fù)向提示、相同的種子、相同的CFG值和相同的圖像尺寸。

以下是腳本使用說明,便于你進(jìn)行深入研究:

# 克隆整個倉庫或從此文件夾下載文件
# https://github.com/rajeevsrao/TensorRT/tree/release/8.6/demo/Diffusion
# 像往常一樣創(chuàng)建并激活一個虛擬環(huán)境
python -m venv .venv
## Unix
source .venv/bin/activate
## Windows
.venv\Scripts\activate
# 安裝所需的庫
pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118
pip install transformers accelerate diffusers cuda-python nvtx onnx colored scipy polygraphy
pip install --pre --extra-index-url https://pypi.nvidia.com tensorrt
pip install --pre --extra-index-url https://pypi.ngc.nvidia.com onnx_graphsurgeon
# 可以使用以下行驗證 TensorRT 是否正確安裝
python -c "import tensorrt; print(tensorrt.__version__)"
# 9.3.0.post12.dev1
# 進(jìn)行推理
python demo_txt2img_xl.py "macro shot of a bee collecting nectar from lavender flowers"

測試結(jié)果:

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

?<左右滑動查看更多圖片>

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

結(jié)論:

經(jīng)過模型準(zhǔn)備后(約半個小時,僅在第一次準(zhǔn)備時需要),推理過程似乎加速了很多,每張圖像的生成時間僅為 8 秒,而未經(jīng)優(yōu)化的代碼則需要14秒。我無法確定內(nèi)存消耗情況,因為TensorRT使用了不同的API。

至于圖像的質(zhì)量……在初始狀態(tài)下看起來很驚艷。

何時使用:如果你可以將TensorRT集成到你的流程中,可以嘗試一下??雌饋硎且粋€不錯的優(yōu)化方法,值得一試。

4

組件優(yōu)化

這些優(yōu)化措施對于 Stable Diffusion XL 的各個組件進(jìn)行了修改,從而通過多種不同方式提升其性能。每個單獨的改進(jìn)可能只會帶來一點點提升,但將它們?nèi)拷Y(jié)合起來,就會產(chǎn)生顯著影響。

torch.compile

使用PyTorch 2或更高版本時,我們可以通過 [torch.compile] API(https://pytorch.org/docs/stable/generated/torch.compile.html) 對模型進(jìn)行編譯,以獲得更好的性能。盡管編譯需要一定時間,但后續(xù)調(diào)用將受益于額外的速度提升。

在以前的PyTorch版本中,也可以通過torch.jit.trace API使用跟蹤技術(shù)對模型進(jìn)行編譯。這種即時(just-in-time / JIT)運行時的編譯方法不如新方法高效,因此我們可以忽略此API。

在torch.compile方法中,mode參數(shù)接受以下值:default、reduce-overhead、max-autotune和max-autotune-no-cudagraphs。理論上它們是不同的,但我沒有看到任何區(qū)別,因此我們將使用 reduce-overhead。

Windows操作系統(tǒng)如下所示:

RuntimeError: Windows not yet supported for torch.compile
pipe = AutoPipelineForText2Image.from_pretrained(
  'stabilityai/stable-diffusion-xl-base-1.0',
  use_safetensors=True,
  torch_dtype=torch.float16,
  variant='fp16',
).to('cuda')


pipe.unet = torch.compile(pipe.unet, mode='reduce-overhead', fullgraph=True)


generator = torch.Generator(device='cuda')


for i, generation in enumerate(queue, start=1):
  generator.manual_seed(generation['seed'])


  image = pipe(
    prompt=generation['prompt'],
    generator=generator,
  ).images[0]


  image.save(f'image_{i}.png')

我們將評估編譯模型所需的時間以及每一個連續(xù)生成所需的時間。

測試結(jié)果:

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

結(jié)論:

一項能很快帶來成效的簡單優(yōu)化。

何時使用:當(dāng)生成的圖片足夠多,值得承受編譯時間時就可以使用這種技術(shù)。

OneDiff

OneDiff是一個適配了Diffusers、ComfyUI和Stable Diffusion webUI應(yīng)用框架的優(yōu)化庫。其名字的字面意思是:一行代碼就能加速擴(kuò)散模型。

該庫采用了量化、注意力機(jī)制改進(jìn)和模型編譯等技術(shù)。

安裝該加速引擎只需添加幾個庫,但如果你使用的是其他CUDA版本,或者想要使用不同的安裝方法,可以參考技術(shù)文檔進(jìn)行安裝(https://github.com/siliconflow/onediff#1-install-oneflow)。

pip install --pre oneflow -f https://github.com/siliconflow/oneflow_releases/releases/expanded_assets/community_cu118


pip install --pre onediff

如果你使用的是Windows或macOS,則必須自己編譯該庫。

RuntimeError: This package is a placeholder. Please install oneflow following the instructions in https://github.com/Oneflow-Inc/oneflow#install-oneflow

OneDiff創(chuàng)建者還提供了一個企業(yè)版,承諾額外提供20%的速度(甚至更多),盡管我無法驗證這一點,而且他們也沒有提供太多細(xì)節(jié)。

類似于torch.compile,所需的代碼只有一行,可以改變pipe.unet 的行為。

import oneflow as flow
from onediff.infer_compiler import oneflow_compile


# ...


pipe = AutoPipelineForText2Image.from_pretrained(
  'stabilityai/stable-diffusion-xl-base-1.0',
  use_safetensors=True,
  torch_dtype=torch.float16,
  variant='fp16',
).to('cuda')


pipe.unet = oneflow_compile(pipe.unet)


generator = torch.Generator(device='cuda')


with flow.autocast('cuda'):
  for i, generation in enumerate(queue, start=1):
    generator.manual_seed(generation['seed'])


    image = pipe(
      prompt=generation['prompt'],
      generator=generator,
    ).images[0]


    image.save(f'image_{i}.png')

讓我們看看它是否符合預(yù)期。

測試結(jié)果:

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

?<左右滑動查看更多圖片>

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

結(jié)論:

OneDiff稍微改變了圖像結(jié)構(gòu),但這是一個有利的改變。在interior圖像中,我們可以看到有一個bug通過變成一個陰影的方式被修復(fù)了,。

編譯時間非常短,比torch.compile快得多。

OneDiff使推理時間縮短了45%,超過了所有競品的優(yōu)化速度(Stable Fast、TensorRT 和 torch.compile)。

令人驚訝的是(與Stable Fast不同),其內(nèi)存使用量并沒有增加。

何時使用:建議一直使用。它提高了生成結(jié)果的視覺質(zhì)量,推理時間幾乎減半,唯一的代價是在編譯時需要稍微等待。非常漂亮的工作!

Channels-last內(nèi)存格式

Channels-last內(nèi)存格式組織數(shù)據(jù),用以將顏色通道(color channel)儲存在張量的最后一個緯度中。

默認(rèn)情況下,張量采用的是NCHW格式,對應(yīng)著以下四個維度:

  1. N(數(shù)量):同時生成多少張圖像(批大?。?。

  2. C(通道):圖像具有多少個通道。

  3. H(高度):圖像的高度(以像素為單位)。

  4. W(寬度):圖像的寬度(以像素為單位)。

相比之下,使用這種技術(shù),以NHWC格式將張量數(shù)據(jù)重新排序,將通道數(shù)放在最后。

pipe = AutoPipelineForText2Image.from_pretrained(
  'stabilityai/stable-diffusion-xl-base-1.0',
  use_safetensors=True,
  torch_dtype=torch.float16,
  variant='fp16',
).to('cuda')


pipe.unet.to(memory_format=torch.channels_last)


generator = torch.Generator(device='cuda')


for i, generation in enumerate(queue, start=1):
  generator.manual_seed(generation['seed'])


  image = pipe(
    prompt=generation['prompt'],
    generator=generator,
  ).images[0]


  image.save(f'image_{i}.png')

使用以下命令,檢查張量是否已重新排序(將其放置在重排序之前和之后):

print(pipe.unet.conv_out.state_dict()['weight'].stride())

雖然channels-last內(nèi)存格式在某些情況下可能會提高效率并減少內(nèi)存使用,但它不兼容某些神經(jīng)網(wǎng)絡(luò),甚至可能會降低性能。因此,我們可以將其排除。

測試結(jié)果:

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

結(jié)論:

在Stable Diffusion XL中,U-Net模型似乎并沒有從這種優(yōu)化中受益,但即使這樣,知識也不會占用太多空間對吧?

何時使用:永遠(yuǎn)別用。

FreeU

FreeU是第一個也是唯一一個不改善推理時間或內(nèi)存使用情況,而改善圖像結(jié)果質(zhì)量的優(yōu)化技術(shù)。

這種技術(shù)平衡了U-Net架構(gòu)中兩個關(guān)鍵元素的貢獻(xiàn):skip connections(跳躍連接,引入高頻細(xì)節(jié))和backbone feature maps(主干特征圖,提供語義信息)。

換句話說,F(xiàn)reeU 抵消了圖像中不自然細(xì)節(jié)的引入,提供了更真實的視覺結(jié)果。

pipe = AutoPipelineForText2Image.from_pretrained(
  'stabilityai/stable-diffusion-xl-base-1.0',
  use_safetensors=True,
  torch_dtype=torch.float16,
  variant='fp16',
).to('cuda')


pipe.enable_freeu(s1=0.9, s2=0.2, b1=1.3, b2=1.4)


generator = torch.Generator(device='cuda')


for i, generation in enumerate(queue, start=1):
  generator.manual_seed(generation['seed'])


  image = pipe(
    prompt=generation['prompt'],
    generator=generator,
  ).images[0]


  image.save(f'image_{i}.png')

你可以調(diào)整這些值,盡管它們是Stable Diffusion XL的推薦值。

如需要更多信息,可查看項目:https://github.com/ChenyangSi/FreeU#parameters

測試結(jié)果:

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

?<左右滑動查看更多圖片>

結(jié)論:

我之前從未嘗試過FreeU,但這個結(jié)果給我留下了深刻印象。盡管圖片的結(jié)構(gòu)與原始輸入有所不同,但我認(rèn)為它們更忠實于提示,并專注于提供最佳視覺質(zhì)量,而不會陷入細(xì)節(jié)的瑣碎之中。

同時我發(fā)現(xiàn)這個技術(shù)也有一個問題,即圖片失去了一些連貫性。例如,沙發(fā)頂部有一盆植物,蜜蜂有三只翅膀。這表明盡管圖片視覺上引人注目,但可能缺乏一定的邏輯一致性或現(xiàn)實感。

何時使用:當(dāng)我們想要獲得更具創(chuàng)意、更高視覺質(zhì)量的結(jié)果時使用(盡管這也取決于我們所追求的圖像風(fēng)格)。

VAE FP16 fix

正如在批處理優(yōu)化中看到的,Stable Diffusion XL中默認(rèn)包含的VAE模型無法在FP16格式下運行。在解碼圖像之前,pipeline會執(zhí)行一個方式,以使強(qiáng)制模型以FP32格式工作 (pipe.upcast_vae())。而在之前的FP16優(yōu)化中,將模型以FP32格式運行是一種不必要的資源浪費。

用戶madebyollin(也是TAESD的創(chuàng)作者,稍后我們將看到)已經(jīng)創(chuàng)建了這個模型的一個修復(fù)版,使其可以在FP16格式下運行。

我們只需導(dǎo)入這個VAE并替換原始版本:(https://huggingface.co/madebyollin/sdxl-vae-fp16-fix)

from diffusers import AutoPipelineForText2Image, AutoencoderKL


# ...


vae = AutoencoderKL.from_pretrained(
  'madebyollin/sdxl-vae-fp16-fix',
  use_safetensors=True,
  torch_dtype=torch.float16,
).to('cuda')


pipe = AutoPipelineForText2Image.from_pretrained(
  'stabilityai/stable-diffusion-xl-base-1.0',
  use_safetensors=True,
  torch_dtype=torch.float16,
  variant='fp16',
  vae=vae,
).to('cuda')


generator = torch.Generator(device='cuda')


for i, generation in enumerate(queue, start=1):
  generator.manual_seed(generation['seed'])


  image = pipe(
    prompt=generation['prompt'],
    generator=generator,
  ).images[0]


  image.save(f'image_{i}.png')

測試結(jié)果:

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

?<左右滑動查看更多圖片>

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

結(jié)論:

圖像視覺質(zhì)量與原始模型幾乎相同,沒有質(zhì)量損失。

內(nèi)存使用量減少了將近15%,對于這一簡單改進(jìn)來說是相當(dāng)不錯的結(jié)果。

何時使用:可以一直使用,除非你更傾向于使用Tiny VAE優(yōu)化(https://www.felixsanz.dev/articles/ultimate-guide-to-optimizing-stable-diffusion-xl#tiny-vae)。

VAE slicing

當(dāng)同時生成多張圖像時(增加批大?。?,VAE會同時解碼所有張量(并行)。這會大大增加內(nèi)存使用量。為避免這種情況,可以使用VAE切片技術(shù)逐個解碼張量(串行)。這與我們在批處理優(yōu)化中手動操作的方式幾乎相同。

舉例來說,無論使用的批大小為1、2、8還是32,VAE的內(nèi)存消耗都會保持不變,與此相對應(yīng)的是,會有一個幾乎不可察覺的少量時間損失。

pipe = AutoPipelineForText2Image.from_pretrained(
  'stabilityai/stable-diffusion-xl-base-1.0',
  use_safetensors=True,
  torch_dtype=torch.float16,
  variant='fp16',
).to('cuda')


pipe.enable_vae_slicing()


generator = torch.Generator(device='cuda')


for i, generation in enumerate(queue, start=1):
  generator.manual_seed(generation['seed'])


  image = pipe(
    prompt=generation['prompt'],
    generator=generator,
  ).images[0]


  image.save(f'image_{i}.png')

批大小為1時,這一優(yōu)化技術(shù)沒有任何作用。由于在測試中使用的批處理大小為1,因此我們將跳過測試結(jié)果,直接給出結(jié)論。

結(jié)論:

這一優(yōu)化技術(shù)試圖在增加批大小時減少內(nèi)存使用,而批大小的增加恰恰是導(dǎo)致內(nèi)存使用增加的最關(guān)鍵因素。因此,這種優(yōu)化技術(shù)本身存在矛盾。

何時使用:建議僅在有一個完善的流程,同時生成多張圖像,并且VAE執(zhí)行是瓶頸時使用這種優(yōu)化技術(shù)。換句話說,適合使用這種技術(shù)的情況很少。

VAE tiling

當(dāng)生成高分辨率圖像(如4K/8K)時,VAE往往成為瓶頸。解碼這么大尺寸的圖像不僅需要花費幾分鐘時間,而且還會消耗大量內(nèi)存。經(jīng)常會遇到如下問題:torch.cuda.OutOfMemoryError: CUDA out of memory.

通過這種優(yōu)化技術(shù),張量被分割成幾部分(就像它們是切片一樣),然后逐個解碼,最后再重新連接起來形成圖像。這樣,VAE不必一次性解碼所有內(nèi)容。

pipe = AutoPipelineForText2Image.from_pretrained(
  'stabilityai/stable-diffusion-xl-base-1.0',
  use_safetensors=True,
  torch_dtype=torch.float16,
  variant='fp16',
).to('cuda')


pipe.enable_vae_tiling()


generator = torch.Generator(device='cuda')


for i, generation in enumerate(queue, start=1):
  generator.manual_seed(generation['seed'])


  image = pipe(
    prompt=generation['prompt'],
    generator=generator,
    height=4096,
    width=4096,
  ).images[0]


  image.save(f'image_{i}.png')

因為圖像被分割成了多個部分,然后再重新連接起來,所以連接處可能會出現(xiàn)一些微小的顏色差異或瑕疵。然而,通常情況下這種差異都不太常見或不容易被察覺。

測試結(jié)果:

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

結(jié)論:

這種優(yōu)化技術(shù)相對簡單易懂:如果需要生成非常高分辨率的圖像,而你的顯卡內(nèi)存不足,這將是實現(xiàn)這一目標(biāo)的唯一選擇。

何時使用:永遠(yuǎn)不要使用這種優(yōu)化技術(shù)。非常高分辨率的圖像存在缺陷,因為Stable Diffusion模型并沒有針對這種任務(wù)進(jìn)行訓(xùn)練。如果需要增加分辨率,應(yīng)該使用一個上采樣器(upscaler)。

Tiny VAE

在Stable Diffusion XL中使用了一個擁有5000萬個參數(shù)的32 bit VAE。由于這個組件是可互換的,我們將使用一個名為TAESD的VAE。這個小模型只有100萬個參數(shù),是原始VAE的精簡版,同時能夠在16 bit格式下運行。

from diffusers import AutoPipelineForText2Image, AutoencoderTiny


# ...


vae = AutoencoderTiny.from_pretrained(
  'madebyollin/taesdxl',
  use_safetensors=True,
  torch_dtype=torch.float16,
).to('cuda')


pipe = AutoPipelineForText2Image.from_pretrained(
  'stabilityai/stable-diffusion-xl-base-1.0',
  use_safetensors=True,
  torch_dtype=torch.float16,
  variant='fp16',
  vae=vae,
).to('cuda')


generator = torch.Generator(device='cuda')


for i, generation in enumerate(queue, start=1):
  generator.manual_seed(generation['seed'])


  image = pipe(
    prompt=generation['prompt'],
    generator=generator,
  ).images[0]


  image.save(f'image_{i}.png')

犧牲圖像質(zhì)量,以獲取更快的速度和更少的內(nèi)存使用是否值得?

測試結(jié)果:

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

?<左右滑動查看更多圖片>

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

結(jié)論:

由于Tiny VAE是一個更小的模型,并且能夠在16 bit格式下運行,因此內(nèi)存使用量大幅減少。

Tiny VAE并沒有顯著減少推理時間。

盡管圖像略微改變,尤其是似乎增加了一些對比度和紋理,但我認(rèn)為這種變化不明顯。因此,圖像質(zhì)量的損失是可以接受的。

何時使用:如果你需要一直減少內(nèi)存使用量,那么建議始終使用Tiny VAE。有了這個模型,甚至可以在不采用其他優(yōu)化策略的情況下,用8GB顯卡運行推理過程。即使不需要減少內(nèi)存使用,使用Tiny VAE也是一個不錯的選擇,因為它似乎沒有負(fù)面影響。

5

參數(shù)優(yōu)化

在這個類別中,我們將以犧牲圖像質(zhì)量為代價,修改一些參數(shù)以獲得額外速度,希望這種犧牲不會太大。

Stable Diffusion XL使用Euler作為默認(rèn)采樣器。雖然可能有更快的采樣器,但Euler本身已經(jīng)屬于快速采樣器范疇,因此將Euler替換為其他采樣器并不會帶來顯著的優(yōu)化效果。

步數(shù)(Step)

采用默認(rèn)SDXL,通過50步來清除一個充滿噪音的張量。步數(shù)越多,噪音清除效果就越好,但推理時間也會相應(yīng)增加。使用num_inference_steps參數(shù),我們可以指定想要使用的步數(shù)。

我們將分別使用30、25、20和15步,來生成一系列圖像。我們將使用默認(rèn)值(50)作為比較基準(zhǔn)。

pipe = AutoPipelineForText2Image.from_pretrained(
  'stabilityai/stable-diffusion-xl-base-1.0',
  use_safetensors=True,
  torch_dtype=torch.float16,
  variant='fp16',
).to('cuda')


generator = torch.Generator(device='cuda')


for i, generation in enumerate(queue, start=1):
  generator.manual_seed(generation['seed'])


  image = pipe(
    prompt=generation['prompt'],
    num_inference_steps=30,
    generator=generator,
  ).images[0]


  image.save(f'image_{i}.png')

盡管減少步數(shù)可以縮短推理時間,但我們更感興趣的是保持在一定范圍的步數(shù),以盡可能地維持圖像的質(zhì)量和結(jié)構(gòu)。如果我們的圖像質(zhì)量大幅下降,就算節(jié)省了大量時間也沒有意義。接下來我們來探索步數(shù)數(shù)量的極限。

測試結(jié)果:

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

?<左右滑動查看更多圖片>

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

結(jié)論:

肖像照片(Portrait):在15和20步時,質(zhì)量尚可,但結(jié)構(gòu)有所不同。25步及以上時,我發(fā)現(xiàn)圖像質(zhì)量和結(jié)構(gòu)相當(dāng)不錯。

室內(nèi)照片(Interior):在15步時,仍然沒有達(dá)到期望的結(jié)構(gòu)。在20步時,結(jié)果相當(dāng)不錯,但某些元素仍有缺失。因此,我認(rèn)為至少需要25步。

微距攝影(Macro):在微距攝影中,即使只有15步,細(xì)節(jié)水平也相當(dāng)驚人。我不知道應(yīng)該選哪個步數(shù),因為所有選項都是有效和正確的。

3D圖像:在3D風(fēng)格的圖像中,少量步數(shù)會導(dǎo)致產(chǎn)生大量缺陷,甚至在某些區(qū)域會出現(xiàn)模糊。盡管30步的圖像還不錯,但我更傾向于使用50步(或者40步)的結(jié)果。

總的來說,根據(jù)生成的圖像風(fēng)格,可以選擇使用更多或更少的步數(shù)。但是,在25-30步時可以獲得相當(dāng)不錯的質(zhì)量。這樣做可以將推理時間縮短約40%,是一種相當(dāng)顯著的提升。

何時使用:當(dāng)測試提示或調(diào)整參數(shù),并且想要快速生成圖像時,這是一個很好的優(yōu)化方法。調(diào)試完所有參數(shù)和提示后,可以增加步數(shù),以獲取最高質(zhì)量的圖像。根據(jù)具體的使用情況,可以選擇是否永久采用這種優(yōu)化方法。

禁用 CFG

正如文章“How Stable Diffusion works”所說,無分類器引導(dǎo)(classifier-free guidance)技術(shù)負(fù)責(zé)調(diào)整噪音預(yù)測器與特定標(biāo)簽之間的距離。

舉例來說,假設(shè)我們有一個關(guān)于汽車的正向提示和一個關(guān)于玩具的負(fù)向提示。CFG技術(shù)可以調(diào)整噪音預(yù)測器與“汽車”標(biāo)簽之間的距離,使其更接近“汽車”標(biāo)簽所代表的概念,同時遠(yuǎn)離“玩具”標(biāo)簽所代表的概念。這樣做可以確保生成的圖像更符合“汽車”的特征,而不受“玩具”的影響。這是一種非常有效的控制條件圖像生成法。

“How to implement Stable Diffusion(https://www.felixsanz.dev/articles/how-to-implement-stable-diffusion)”一文介紹了如何實現(xiàn)CFG技術(shù),并且說明了它引入需要復(fù)制張量的需求:

# As we're using classifier-free guidance, we duplicate the tensor to avoid making two passes
# One pass will be for the conditioned values and another for the unconditioned values
latent_model_input = torch.cat([latents] * 2)

這意味著噪音預(yù)測器在每步上需要花費兩倍的時間。

在生成圖像的早期階段,啟用CFG技術(shù)對于獲得質(zhì)量良好且符合我們提示的圖像至關(guān)重要。一旦噪音預(yù)測器成功地開始產(chǎn)生符合預(yù)期的圖像,我們就可能不再需要繼續(xù)使用CFG技術(shù)了。在這一優(yōu)化方法中,我們將探索在圖像生成過程中停用CFG技術(shù)的影響。

代碼很簡單,我們創(chuàng)建了一個函數(shù),負(fù)責(zé)在步數(shù)達(dá)到指定值后禁用CFG技術(shù)(pipe._guidance_scale = 0.0)。此外,停止使用CFG技術(shù)后,將不再需要復(fù)制張量。

pipe = AutoPipelineForText2Image.from_pretrained(
  'stabilityai/stable-diffusion-xl-base-1.0',
  use_safetensors=True,
  torch_dtype=torch.float16,
  variant='fp16',
).to('cuda')


def callback_dynamic_cfg(pipe, step_index, timestep, callback_kwargs):
  if step_index == int(pipe.num_timesteps * 0.5):
    callback_kwargs['prompt_embeds'] = callback_kwargs['prompt_embeds'].chunk(2)[-1]
    callback_kwargs['add_text_embeds'] = callback_kwargs['add_text_embeds'].chunk(2)[-1]
    callback_kwargs['add_time_ids'] = callback_kwargs['add_time_ids'].chunk(2)[-1]
    pipe._guidance_scale = 0.0


  return callback_kwargs


generator = torch.Generator(device='cuda')


for i, generation in enumerate(queue, start=1):
  generator.manual_seed(generation['seed'])


  image = pipe(
    prompt=generation['prompt'],
    generator=generator,
    callback_on_step_end=callback_dynamic_cfg,
    callback_on_step_end_tensor_inputs=['prompt_embeds', 'add_text_embeds', 'add_time_ids'],
  ).images[0]


  image.save(f'image_{i}.png')

由于callback_on_step_end參數(shù),在每一步結(jié)束時這個函數(shù)作為回調(diào)函數(shù)被執(zhí)行。我們需要使用callback_on_step_end_tensor_inputs參數(shù),確定我們將在回調(diào)函數(shù)內(nèi)部修改的張量。

我們來看看在圖像生成過程的最后25%和后半部分(50%),停用CFG技術(shù)會發(fā)生什么。

測試結(jié)果:

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

?<左右滑動查看更多圖片>

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

結(jié)論:

正如我們所預(yù)期的,在50%的情況下停用CFG,可以使每張圖像的推理時間減少25%(并非總體時間,因為模型加載時間也計入其中)。這是因為如果使用CFG執(zhí)行50步操作,模型實際上清理了100個張量。而使用這種優(yōu)化方法,模型在前25步清理了50個張量,在接下來的25步中清理了一半(25個張量)。所以,75/100相當(dāng)于跳過了25%的工作量。在停用CFG達(dá)到75%的情況下,每張圖像的推理時間減少12.5%。

圖像質(zhì)量似乎有所下降但不太明顯。這可能是因為沒有使用負(fù)向提示,而使用CFG的主要優(yōu)勢就在于能夠應(yīng)用負(fù)向提示。使用更好的提示肯定會提高質(zhì)量,但在停用CFG達(dá)到75%的情況下,這種影響幾乎可以忽略不計。

何時使用:當(dāng)你對圖像生成速度要求較高,且能夠接受一定程度的質(zhì)量損失,那么可以積極采用這種優(yōu)化方法(例如,用于測試提示或參數(shù)時)。通過稍后停用CFG,可以提高速度而不犧牲質(zhì)量。

細(xì)化模型(Refiner)

那么細(xì)化模型呢?雖然我們已經(jīng)優(yōu)化了基礎(chǔ)模型,但Stable Diffusion XL的一個主要優(yōu)勢是,它還有一個專門細(xì)化細(xì)節(jié)的模型。這個模型顯著提高了生成的圖像質(zhì)量。

默認(rèn)情況下,基礎(chǔ)模型使用11.24 GB的內(nèi)存。當(dāng)同時使用細(xì)化模型時,內(nèi)存需求增加到了17.38 GB。但要記住,由于它具有相同的組件(除了第一個文本編碼器),大多數(shù)優(yōu)化也可以應(yīng)用于這個模型。

在使用細(xì)化模型進(jìn)行預(yù)熱時,因為需要預(yù)熱兩個不同的模型,所以會有些復(fù)雜。為實現(xiàn)這一點,我們首先從基礎(chǔ)模型獲取結(jié)果,然后將其通過細(xì)化模型進(jìn)行處理:

for generation in queue:
  image = base(generation['prompt'], output_type='latent').images
  refiner(generation['prompt'], image=image)

細(xì)化模型有兩種不同的使用方式,我們將分別討論。

專家去噪器集成(Ensemble of Expert Denoisers)

專家去噪器集成是指圖像生成的方法,其過程從基礎(chǔ)模型開始,最后使用細(xì)化模型結(jié)束。在整個過程中,不會生成任何圖像,而是基礎(chǔ)模型在指定數(shù)量的步數(shù)(總步數(shù)的一部分)內(nèi)清理張量,然后將張量傳遞給細(xì)化模型以完成處理。

可以這樣說,它們共同工作以生成結(jié)果(基礎(chǔ)模型+細(xì)化器)。

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

就代碼而言,基礎(chǔ)模型在使用denoising_end=0.8參數(shù)時,會在處理過程的80%處停止其工作,并且通過 output_type='latent' 返回張量。

細(xì)化模型通過image參數(shù)接收到這個張量(諷刺的是,它并不是一個圖像)。然后,細(xì)化模型開始清理這個張量,通過參數(shù)denoising_start=0.8假設(shè)已經(jīng)完成了80%的工作。我們再次指定了整個處理過程的步數(shù) (num_inference_steps),以便它計算剩余需要清理的步數(shù)。也就是說,如果我們使用50步,并且在80%處進(jìn)行了變化,那么基礎(chǔ)模型將會在前40步清理張量,細(xì)化模型將為剩余的10步進(jìn)行精細(xì)化處理,以完善剩余細(xì)節(jié)。

from diffusers import AutoPipelineForText2Image, AutoPipelineForImage2Image


# ...


base = AutoPipelineForText2Image.from_pretrained(
  'stabilityai/stable-diffusion-xl-base-1.0',
  use_safetensors=True,
  torch_dtype=torch.float16,
  variant='fp16',
).to('cuda')


refiner = AutoPipelineForImage2Image.from_pretrained(
  'stabilityai/stable-diffusion-xl-refiner-1.0',
  use_safetensors=True,
  torch_dtype=torch.float16,
  variant='fp16',
).to('cuda')


generator = torch.Generator(device='cuda')


for i, generation in enumerate(queue, start=1):
  generator.manual_seed(generation['seed'])


  image = base(
    prompt=generation['prompt'],
    generator=generator,
    num_inference_steps=50,
    denoising_end=0.8,
    output_type='latent',
  ).images # Remember that here we do not access images[0], but the entire tensor


  image = refiner(
    prompt=generation['prompt'],
    generator=generator,
    num_inference_steps=50,
    denoising_start=0.8,
    image=image,
  ).images[0]


  image.save(f'image_{i}.png')

我們將在50、40、30和20步時生成圖像,并在處理到0.9和0.8時切換到細(xì)化模型。

作為參考,我們還將包括在所有比較中作為基礎(chǔ)的圖像(只使用基礎(chǔ)模型,共50步)。

測試結(jié)果:

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

?<左右滑動查看更多圖片>

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

結(jié)論:

毫無疑問,使用細(xì)化模型顯然會極大地改善結(jié)果。

那么應(yīng)該在何時使用細(xì)化模型來處理圖像呢?顯然,可以看出在 0.9 處得到的結(jié)果比在 0.8 處更好,因為細(xì)化模型旨在優(yōu)化最終細(xì)節(jié),不應(yīng)該用于改變圖像結(jié)構(gòu)。

我認(rèn)為,無論步數(shù)是多少,細(xì)化模型似乎都能提供非常高的視覺質(zhì)量結(jié)果。唯一會改變的是圖像結(jié)構(gòu),但即使只有30步,視覺質(zhì)量也很高。

同時,我們還要考慮到當(dāng)步數(shù)減少到40以下時,所需時間會顯著減少。

何時使用:每當(dāng)我們想要利用細(xì)化模型來提高圖像的視覺質(zhì)量時,就可以使用它。至于參數(shù),只要我們不追求最佳的質(zhì)量,就可以使用30或40步。當(dāng)然始終要在0.9處切換到細(xì)化模型。

圖像到圖像(Image-to-image)

在Stable Diffusion XL中,經(jīng)典的圖像到圖像(img2img)方法并不新鮮。這種方法是使用基礎(chǔ)模型生成完整圖像,然后將生成的圖像和原始提示一起傳遞給細(xì)化模型,細(xì)化模型使用這些條件生成新的圖像。

換句話說,在img2img方法中,這兩個模型是獨立工作的(基礎(chǔ)模型->細(xì)化模型)。

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

由于兩個過程是獨立的,因此相對容易應(yīng)用本文中的優(yōu)化方法。盡管如此,代碼并沒有太大的差異,只是簡單地生成了一個圖像,并將其用作細(xì)化模型的參數(shù)。

from diffusers import AutoPipelineForText2Image, AutoPipelineForImage2Image


# ...


base = AutoPipelineForText2Image.from_pretrained(
  'stabilityai/stable-diffusion-xl-base-1.0',
  use_safetensors=True,
  torch_dtype=torch.float16,
  variant='fp16',
).to('cuda')


refiner = AutoPipelineForImage2Image.from_pretrained(
  'stabilityai/stable-diffusion-xl-refiner-1.0',
  use_safetensors=True,
  torch_dtype=torch.float16,
  variant='fp16',
).to('cuda')


generator = torch.Generator(device='cuda')


for i, generation in enumerate(queue, start=1):
  generator.manual_seed(generation['seed'])


  image = base(
    prompt=generation['prompt'],
    generator=generator,
    num_inference_steps=50,
  ).images[0]


  image = refiner(
    prompt=generation['prompt'],
    generator=generator,
    num_inference_steps=10,
    image=image,
  ).images[0]


  image.save(f'image_{i}.png')

我們將使用基礎(chǔ)模型在50、40、30和20步處生成圖像,然后再通過細(xì)化模型添加額外的20步和10步的組合。

作為參考,我們還包含了所有比較的基礎(chǔ)圖像,這張圖像是基礎(chǔ)模型處理的結(jié)果,只進(jìn)行了50步的處理。

測試結(jié)果:

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

?<左右滑動查看更多圖片>

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

結(jié)論:

在圖像到圖像(img2img)模式中,細(xì)化模型的表現(xiàn)不如人意。

當(dāng)我們在基礎(chǔ)模型中使用足夠的步數(shù)時,似乎細(xì)化模型被迫向本不需要的部分添加細(xì)節(jié)。換句話說,這是在畫蛇添足。

另一方面,如果我們在基礎(chǔ)模型中使用較少的步數(shù),結(jié)果會稍微好一些。這是因為使用如此少的步數(shù),基礎(chǔ)模型無法添加細(xì)微的細(xì)節(jié),為細(xì)化模型提供了更大的發(fā)揮空間。

同時,我們也必須考慮通過減少步數(shù)來減少時間。如果我們使用太多步數(shù),將會受到顯著的損失。

何時使用:首先要記住的是,使用細(xì)化模型的目的是最大化視覺質(zhì)量。在這種情況下,我們可以增加步數(shù),因此,“專家去噪器集成”方法是最佳選擇。我認(rèn)為,使用少量步數(shù)無法獲得更好的視覺質(zhì)量,也不會提高生成速度,與其他方法相比也不具備優(yōu)勢。因此,在圖像到圖像模式下使用細(xì)化模型有其優(yōu)勢,但其優(yōu)勢并不突出。

6

結(jié)論

開始寫這篇文章時,我并沒有想到會深入研究到這個程度。我能夠理解直接跳到結(jié)論部分的讀者,同時我也很佩服看了所有優(yōu)化內(nèi)容的讀者。希望閱讀完本文后,讀者們能夠有所所獲。

根據(jù)目標(biāo)和可用的硬件,我們需要應(yīng)用不同的優(yōu)化方法。讓我們以表格的形式,總結(jié)所有的優(yōu)化措施以及它們引入的改進(jìn)(或損失)。

理論上來說,“中立”的優(yōu)化方法是該類別中一個有利的改變,但其可解釋性可能有爭議,或者僅適用于某些特定用例。

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

最快速度

使用基礎(chǔ)模型結(jié)合OneDiff+Tiny VAE+75%處禁用CFG+30步,可以在幾乎質(zhì)量無損的情況下實現(xiàn)最短的生成時間,從而達(dá)到最快速度。

在擁有RTX 3090顯卡的情況下,可以在僅4.0秒的時間內(nèi)生成圖像,內(nèi)存消耗為6.91 GB,因此甚至可以在具有8 GB內(nèi)存的顯卡上運行。

我們還可以添加DeepCache以進(jìn)一步加快流程,但問題是,它與禁用CFG優(yōu)化不兼容,一旦禁用它,最終速度就會增加。

使用相同的配置,A100顯卡可以在2.7秒內(nèi)生成圖像。在全新的 H100 上,推理時間僅為2.0秒。

不到4GB的內(nèi)存使用量

在使用Sequential CPU Offload時,瓶頸在于VAE。因此,將這種優(yōu)化與VAE FP16 fix或Tiny VAE結(jié)合使用,將分別需要2.56 GB和0.68 GB的內(nèi)存使用量。雖然內(nèi)存使用量低得離譜,但推理時間會讓你覺得有必要去換一張擁有更多內(nèi)存的新顯卡。

不到6GB的內(nèi)存使用量

通過使用批處理優(yōu)化,內(nèi)存使用量降低至5.77 GB,從而使得在擁有6 GB內(nèi)存的顯卡上可以使用 Stable Diffusion XL 生成圖像。在這種情況下,沒有質(zhì)量損失或推理時間增加,如果我們想使用細(xì)化模型也沒有問題,內(nèi)存消耗是一樣的。

另一個選擇是使用Model CPU Offload,這也足以減少內(nèi)存使用,只不過會有一點時間上的損失。

通過使用VAE FP16 fix或Tiny VAE優(yōu)化VAE,我們可以稍微加快推理過程。

如果我們想要稍微加快推理過程并在12.9秒內(nèi)生成圖像,我們可以通過使用VAE FP16 fix來實現(xiàn)這一點。而且,如果我們不介意稍微改變結(jié)果,我們還可以進(jìn)一步優(yōu)化,通過使用Tiny VAE,將內(nèi)存消耗降低到5.6 GB,生成時間縮短到12.6秒。

請記住,仍然可以應(yīng)用其他優(yōu)化措施來減少生成時間。

不到8GB的內(nèi)存使用量

突破了6 GB的內(nèi)存限制之后,就可以開啟新的優(yōu)化選擇。

正如之前所看到的,使用OneDiff+Tiny VAE將內(nèi)存使用量降至6.91 GB,并實現(xiàn)了可能的最低推理時間。因此,如果你的顯卡至少有8 GB內(nèi)存,這可能是你的最佳選擇。

【OneDiff v0.12.1正式發(fā)布(生產(chǎn)環(huán)境穩(wěn)定加速SD&SVD)】本次更新包含以下亮點,歡迎體驗新版本:github.com/siliconflow/onediff

*??更新SDXL和SVD的SOTA性能

*? 全面支持SD和SVD動態(tài)分辨率運行

*? 編譯/保存/加載HF Diffusers的pipeline

*? HF Diffusers的快速LoRA加載和切換

*? 加速了InstantID(加速1.8倍)

*? 加速了SDXL Lightning

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

(SDXL?E2E?Time)

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff

(SVD?E2E?Time)

更多詳情:https://medium.com/@SiliconFlowAI/

其他人都在看

  • 800+頁免費“大模型”電子書

  • LLM推理的極限速度

  • 強(qiáng)化學(xué)習(xí)之父:通往AGI的另一種可能

  • 好久不見!OneFlow 1.0全新版本上線

  • LLM推理入門指南②:深入解析KV緩存

  • 僅需50秒,AI讓你的通話彩鈴變身短視頻

  • OneDiffx“圖生生”,電商AI圖像處理新范式

Stable Diffusion XL優(yōu)化終極指南,前沿技術(shù),stable diffusion,人工智能,計算機(jī)視覺,onediff文章來源地址http://www.zghlxwxcb.cn/news/detail-858740.html

到了這里,關(guān)于Stable Diffusion XL優(yōu)化終極指南的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Stable Diffusion XL 0.9

    Stable Diffusion XL 0.9

    雖然此前CEO曾陷入種種爭議,但依然不影響Stability AI登上時代雜志。近日,該公司又發(fā)布了Stable Diffusion 的XL 0.9版本,35億+66億雙模型,搭載最大OpenCLIP,讓AI生圖質(zhì)量又有了新的飛躍。 Stable Diffusion又雙叒升級了! 最近,Stability AI發(fā)布了最新版的Stable Diffusion XL 0.9(SDXL 0.9)。

    2024年02月12日
    瀏覽(22)
  • Stable Diffusion-XL

    Stable Diffusion-XL

    開源、免費的Stable Diffusion就能達(dá)到Midjourney水平! 自從Midjourney發(fā)布v5之后,在生成圖像的人物真實程度、手指細(xì)節(jié)等方面都有了顯著改善,并且在prompt理解的準(zhǔn)確性、審美多樣性和語言理解方面也都取得了進(jìn)步。 相比之下,Stable Diffusion雖然免費、開源,但每次都要寫一大長

    2024年02月15日
    瀏覽(28)
  • Stable Diffusion XL訓(xùn)練LoRA

    Stable Diffusion XL訓(xùn)練LoRA

    主要包括SDXL模型結(jié)構(gòu),從0到1訓(xùn)練SDXL以及LoRA教程,從0到1搭建SDXL推理流程。? 【一】SDXL訓(xùn)練初識 Stable Diffusion系列模型的訓(xùn)練主要分成一下幾個步驟,Stable Diffusion XL也不例外: 訓(xùn)練集制作:數(shù)據(jù)質(zhì)量評估,標(biāo)簽梳理,數(shù)據(jù)清洗,數(shù)據(jù)標(biāo)注,標(biāo)簽清洗,數(shù)據(jù)增強(qiáng)等。 訓(xùn)練文

    2024年02月07日
    瀏覽(26)
  • Stable Diffusion 模型分享:DreamShaper XL(夢想塑造者 XL)

    Stable Diffusion 模型分享:DreamShaper XL(夢想塑造者 XL)

    本文收錄于《AI繪畫從入門到精通》專欄,專欄總目錄:點這里。

    2024年03月24日
    瀏覽(27)
  • Stable Diffusion XL on diffusers

    Stable Diffusion XL on diffusers

    翻譯自:https://huggingface.co/docs/diffusers/using-diffusers/sdxl v0.24.0 非逐字翻譯 Stable Diffusion XL (SDXL) 是一個強(qiáng)大的圖像生成模型,其在上一代 Stable Diffusion 的基礎(chǔ)上主要做了如下優(yōu)化: 參數(shù)量增加:SDXL 中 Unet 的參數(shù)量比前一代大了 3 倍,并且 SDXL 還引入了第二個 text-encoder(OpenCL

    2024年03月14日
    瀏覽(25)
  • Stable Diffusion XL 帶來哪些新東西?

    Stable Diffusion XL 帶來哪些新東西?

    前幾天寫了一篇小短文《 Stable Diffusion 即將發(fā)布全新版本》,很快,Stability AI 的創(chuàng)始人兼首席執(zhí)行官 Emad Mostaque 在一條推文中宣布,Stable Diffusion XL 測試現(xiàn)已可用于公開測試。那么這樣一個全新版本會帶來哪些新東西,讓我們眼見為實吧。 不過在開始之前,簡單說明一下:

    2024年02月09日
    瀏覽(23)
  • Stable Diffusion XL(SDXL)原理詳解

    Stable Diffusion XL(SDXL)原理詳解

    ??關(guān)注公眾號 funNLPer 暢讀全文?? 技術(shù)報告:SDXL: Improving Latent Diffusion Models for High-Resolution Image Synthesis 官方代碼:Stability-AI-generative-models 模型權(quán)重:HuggingFace-Stability AI 非官方代碼:Linaqruf/kohya-trainer diffuser庫:diffusers/pipelines/stable_diffusion_xl

    2024年02月10日
    瀏覽(25)
  • Stable Diffusion XL網(wǎng)絡(luò)結(jié)構(gòu)-超詳細(xì)

    Stable Diffusion XL網(wǎng)絡(luò)結(jié)構(gòu)-超詳細(xì)

    Stable Diffusion1.5網(wǎng)絡(luò)結(jié)構(gòu)-超詳細(xì)原創(chuàng)-CSDN博客 以生成圖像1024x1024為例,與SD1.5的3個 CrossAttnDownBlock2D和CrossAttnUpBlock2D 相比,SDXL只有2個,但SDXL的 CrossAttnDownBlock2D模塊有了更多的Transformer模塊,且只進(jìn)行了兩次下采樣,具體的往下看 1.2.1? DownBlock2D 1.2.1.1 ResBolck2D 和SD1.5不一樣的是

    2024年04月25日
    瀏覽(25)
  • Stable Diffusion XL(SDXL)核心基礎(chǔ)知識

    Stable Diffusion XL(SDXL)核心基礎(chǔ)知識

    Stable Diffusion XL 或 SDXL 是最新的圖像生成模型,與以前的 SD 模型(包括 SD 2.1)相比,它專為更逼真的輸出而定制,具有更詳細(xì)的圖像和構(gòu)圖。與Stable DiffusionV1-v2相比,Stable Diffusion XL主要做了如下的優(yōu)化: 對Stable Diffusion原先的U-Net,VAE,CLIP Text Encoder三大件都做了改進(jìn): U-N

    2024年02月01日
    瀏覽(30)
  • 【Stable Diffusion XL】huggingface diffusers 官方教程解讀

    【Stable Diffusion XL】huggingface diffusers 官方教程解讀

    相關(guān)鏈接: GitHub: https://github.com/huggingface/diffusers 官方教程:https://huggingface.co/docs/diffusers/tutorials/tutorial_overview StableDiffuson: https://huggingface.co/blog/stable_diffusion#how-does-stable-diffusion-work Diffusers被設(shè)計成一個用戶友好和靈活的工具箱,用于構(gòu)建適合您用例的擴(kuò)散系統(tǒng)。工具箱的核

    2024年02月06日
    瀏覽(31)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包