Closed Klanly closed 1 year ago
是的,现在输出固定是512*512。
torch有个_native_multi_head_attention可以参考: https://pytorch.org/cppdocs/api/function_namespaceat_1aa4f72ac82c15c7aeef274332b25a543b.html
改用nn.MultiheadAttention就为的是让torch调用这个c api. 省显存用的, 原理大约和xformers, FlashAttention差不多. https://github.com/facebookresearch/xformers https://github.com/HazyResearch/flash-attention
kpi+++++ 我想办法优化一下这个速度吧,现在确实是慢了点,体验比较糟糕。
当初也想搞这玩意不过发现ncnn没法handle动态二维形状, 想说等它支持shape了再说...
还有我看assets/UNetModel-fp16.param, 貌似pnnx没把那一大坨MatMul-Softmax优化成MultiHeadAttention, 原版用einsum的jit code整理后如下: diffusion_embJITbase.py.txt attn1和attn2改成nn.MultiHeadAttention后应该是这样: diffusion_embJITnative.py.txt
这里有些改用nn.MultiHeadAttention的JIT .pt: https://huggingface.co/Larvik/sd470k_a300/tree/main (参考Ailia axinc-ai/ailia-models#830 的三分UNet)
调用JIT为:
diffusion_emb = torch.jit.load('diffusion_emb_pnnx.pt') ... h, emb, hs = diffusion_emb(x, t, cond) h = diffusion_mid(h, emb, cond, *hs[6:]) output = diffusion_out(h, emb, cond, *hs[:6])
pnnx应为:
pnnx diffusion_emb.pt inputshape=[1,4,64,64]f32,[1]i64,[1,77,768]f32 pnnx diffusion_mid.pt inputshape=[2,1280,4,8]f32,[2,1280]f32,[2,77,768]f32,[2,640,8,16]f32,[2,1280,8,16]f32,[2,1280,8,16]f32,[2,1280,4,8]f32,[2,1280,4,8]f32,[2,1280,4,8]f32 pnnx diffusion_out.pt inputshape=[2,1280,16,32]f32,[2,1280]f32,[2,77,768]f32,[2,320,32,64]f32,[2,320,32,64]f32,[2,320,32,64]f32,[2,320,16,32]f32,[2,640,16,32]f32,[2,640,16,32]f32
不过pnnx崩了 @nihui
nn.MultiHeadAttention 转换确实还有问题,没有考虑 q k v 不同shape的情形。。。
是的,现在输出固定是512*512。
- 从某种意义上来说,这个项目并不具有实用性,所以对动态shape的支持没那么优先。动态shape的问题在于,diffusion其实是一个transformer结构cv模型,对动态shape的兼容并没有那么好做。
- multiheadattention的确是老大难,转ncnn经常认不出来。但老实说,multiheadattention的ncnn并没有x86的优化,arm的粗略实现还是我写的,所以在x86上目前还是跑naive的,所以转不转也没差。
大佬大佬,这个unet的onnx怎么转换的,有没有方法啊,是把naifu的ckpt文件直接转化为unet还是怎么搞的,还是用官方的diffuse包的转?我看原模型至少有4g啊,为什么您转换出来的只有不到2g呢
是的,现在输出固定是512*512。
- 从某种意义上来说,这个项目并不具有实用性,所以对动态shape的支持没那么优先。动态shape的问题在于,diffusion其实是一个transformer结构cv模型,对动态shape的兼容并没有那么好做。
- multiheadattention的确是老大难,转ncnn经常认不出来。但老实说,multiheadattention的ncnn并没有x86的优化,arm的粗略实现还是我写的,所以在x86上目前还是跑naive的,所以转不转也没差。
大佬大佬,这个unet的onnx怎么转换的,有没有方法啊,是把naifu的ckpt文件直接转化为unet还是怎么搞的,还是用官方的diffuse包的转?我看原模型至少有4g啊,为什么您转换出来的只有不到2g呢
并不是的,你下载下来的4G ckpt,它里面有好几个模型,其中diffusion使用的unet模型,fp32下也就不到4G,我转出来的onnx是fp16的,因为onnx超过2G就会自动拆包。
kpi+++++ 我想办法优化一下这个速度吧,现在确实是慢了点,体验比较糟糕。
我跟openvino对比了下,在同一台windows上,性能确实差一些,512*512输出。
kpi+++++ 我想办法优化一下这个速度吧,现在确实是慢了点,体验比较糟糕。
我跟openvino对比了下,在同一台windows上,性能确实差一些,512*512输出。
你这CPU有点太慢了,建议换最新的CPU,小于8s不是问题
kpi+++++ 我想办法优化一下这个速度吧,现在确实是慢了点,体验比较糟糕。
我跟openvino对比了下,在同一台windows上,性能确实差一些,512*512输出。
你这CPU有点太慢了,建议换最新的CPU,小于8s不是问题
害!还得再送一个月外卖, 应该就可以换新机器啦!
更新了MHA版本的模型后,要支持动态shape是可以做的,但考虑到动态shape相比静态shape会缺少一些优化,导致内存和速度表现都不如静态shape的模型,所以暂时还是不考虑支持动态shape。
目前已经支持了动态shape了,但仍然只有256x256和512x512的是有优化的,其他shape的没有优化,可能会慢一点。
当初也想搞这玩意不过发现ncnn没法handle动态二维形状, 想说等它支持shape了再说...
还有我看assets/UNetModel-fp16.param, 貌似pnnx没把那一大坨MatMul-Softmax优化成MultiHeadAttention, 原版用einsum的jit code整理后如下: diffusion_embJITbase.py.txt attn1和attn2改成nn.MultiHeadAttention后应该是这样: diffusion_embJITnative.py.txt
这里有些改用nn.MultiHeadAttention的JIT .pt: https://huggingface.co/Larvik/sd470k_a300/tree/main (参考Ailia https://github.com/axinc-ai/ailia-models/issues/830 的三分UNet)
调用JIT为:
pnnx应为:
不过pnnx崩了 @nihui