AMD 6750gre 通过SPAD加速的效果

前情提示:
如果没有安装ROCM或者Anaconda的,可以看我上一篇文章。以下的操作全部在你自己的Anaconda创建的环境中进行,千万不要在系统中搭建,因为万一各个版本出现冲突,那就麻爪了。但是单独的Anaconda环境中就无所谓了,冲突了删除环境重新创建一个新的就完事了。对了,如果你是使用的AMD官网提供的Docker,那你下面安装的代码可能不能直接使用,因为我不确定Docker里面的pyTorch和ROCM的版本是否支持。
以下操作全部在Anaconda创建的环境中进行
以下操作全部在Anaconda创建的环境中进行
以下操作全部在Anaconda创建的环境中进行
测试时需要提前安装diffusers以及对应的常用依赖。
最后说一点就是,目前对于ROCM来说,SPAD是一个不错的选择,但还是有一些我还没有测试到的,例如XFormers、BetterTransformer、MIOpen和hipBLAS以及Flash Attention。这些我都会在后续的文章中依次测试,感兴趣的可以持续关注。

1、diffusers安装

# 使用 pip 安装最新版
pip install diffusers

# 安装开发版(可选)
pip install git+https://github.com/huggingface/diffusers

2、依赖库安装

# 常用依赖
pip install transformers accelerate datasets

# 图像处理库
pip install pillow scipy

# 支持 Stable Diffusion(需登录HuggingFace)
pip install invisible_watermark safetensors

SPAD加速测试的代码:

import torch
from diffusers import StableDiffusionPipeline, DPMSolverMultistepScheduler
from diffusers.utils import logging
import gc

logging.set_verbosity_error()

MODEL_PATH = "/home/wxa/stable-diffusion-2-1" //这里
TEST_PROMPT = "A photo of an astronaut riding a horse on Mars"
SEED = 42


def setup_pipeline(use_sdpa: bool) -> StableDiffusionPipeline:
    torch.cuda.empty_cache()
    gc.collect()

    dtype = torch.float16 if use_sdpa else torch.float32
    attn_impl = "sdpa" if use_sdpa else None

    pipe = StableDiffusionPipeline.from_pretrained(
        MODEL_PATH,
        torch_dtype=dtype,
        attn_implementation=attn_impl,
        variant="fp16" if use_sdpa else None,
        safety_checker=None,
        use_safetensors=True
    ).to("cuda")

    # 过滤废弃参数(包含 skip_prk_steps)
    scheduler_config = dict(pipe.scheduler.config)
    deprecated_keys = ["skip_prk_steps", "clip_sample", "clip_sample_range", "set_alpha_to_one"]
    scheduler_config = {k: v for k, v in scheduler_config.items() if k not in deprecated_keys}

    # 添加新版必要参数
    scheduler_config.update({
        "algorithm_type": "sde-dpmsolver++" if use_sdpa else "dpmsolver++",
        "use_karras_sigmas": True if use_sdpa else False,
        "lambda_min_clipped": -float("inf"),
        "timestep_spacing": "linspace",
        "steps_offset": 1
    })

    pipe.scheduler = DPMSolverMultistepScheduler(** scheduler_config)

    # 显存优化配置
    if use_sdpa:
        pipe.enable_vae_slicing()
        pipe.enable_attention_slicing(1)
    else:
        pipe.enable_model_cpu_offload()
        pipe.enable_attention_slicing(4)

    return pipe


def run_benchmark(pipe: StableDiffusionPipeline, steps: int, res: int) -> dict:
    """执行单次基准测试(带显存保护)"""
    generator = torch.Generator("cuda").manual_seed(SEED)

    try:
        # 预热(减少冷启动误差)
        for _ in range(2):
            _ = pipe(prompt="", num_inference_steps=1, width=64, height=64, generator=generator)

        # 正式测试
        start_event = torch.cuda.Event(enable_timing=True)
        end_event = torch.cuda.Event(enable_timing=True)

        torch.cuda.reset_peak_memory_stats()
        torch.cuda.synchronize()
        start_event.record()

        image = pipe(
            prompt=TEST_PROMPT,
            num_inference_steps=steps,
            width=res,
            height=res,
            generator=generator
        ).images[0]

        end_event.record()
        torch.cuda.synchronize()

        return {
            "time": start_event.elapsed_time(end_event),
            "mem": torch.cuda.max_memory_allocated() / 1e9,
            "image": image
        }
    except RuntimeError as e:
        print(
            f"\033[31m显存不足: {res}x{res}@{steps}steps | 已用显存: {torch.cuda.memory_allocated() / 1e9:.1f}GB\033[0m")
        return None


def benchmark_compare():
    """性能对比测试"""
    test_cases = [
        {"steps": 20, "res": 512},
        {"steps": 32, "res": 768}  # 新增 768x768 测试
        # {"steps": 50, "res": 1024} #如果不信可以将这行注释打开,看看能不能跑起来。
    ]

    # SDPA 模式测试
    print("\n\033[1m=== SDPA (FP16) 模式 ===\033[0m")
    pipe_sdpa = setup_pipeline(use_sdpa=True)
    for case in test_cases:
        result = run_benchmark(pipe_sdpa,  ** case)
        if result:
            print(f"[SDPA] Steps: {case['steps']}, Res: {case['res']}x{case['res']}")
            print(f"Time: {result['time']:.1f}ms | Mem: {result['mem']:.2f}GB")
            result['image'].save(f"sdpa_{case['steps']}s_{case['res']}px.png")

    # 原始模式测试
    print("\n\033[1m=== 原始注意力 (FP32) 模式 ===\033[0m")
    pipe_original = setup_pipeline(use_sdpa=False)
    for case in test_cases:
        print(f"\n\033[33m正在测试 {case['res']}x{case['res']}@{case['steps']}steps...\033[0m")
        result = run_benchmark(pipe_original,  ** case)
        if result:
            print(f"[Original] Steps: {case['steps']}, Res: {case['res']}x{case['res']}")
            print(f"Time: {result['time']:.1f}ms | Mem: {result['mem']:.2f}GB")
            result['image'].save(f"original_{case['steps']}s_{case['res']}px.png")


if __name__ == "__main__":
    if not torch.cuda.is_available():
        raise RuntimeError("需要 NVIDIA 或 AMD 显卡支持")

    # 优化配置(适用于 AMD 显卡)
    if torch.cuda.get_device_properties(0).name.startswith("Radeon"):
        torch.backends.cuda.matmul.allow_tf32 = True
        torch.backends.cudnn.allow_tf32 = True
        # os.environ["HSA_OVERRIDE_GFX_VERSION"] = "11.0.0"  # RX 7000 系列需要

    benchmark_compare()
参数SDPA (FP16)原始注意力 (FP32)提升幅度
512x512 / 20步3.85s/3.04GB5.88s/6.79GB⬆️34.5%/⬇️55.2%
768x768 / 32步18.76s/3.54GB25.11s/9.13GB⬆️25.3%/⬇️61.2%
1024x1024 / 50步\\6750GRE不配测试,这个最低显存要求

如果感兴趣想试试的话,可以将上面{“steps”: 50, “res”: 1024}这行注释解开。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值