自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

PyTorch團隊重寫「分割一切」模型,比原始實現(xiàn)快八倍

人工智能 新聞
我們該如何優(yōu)化 Meta 的「分割一切」模型,PyTorch 團隊撰寫的這篇博客由淺入深的幫你解答。

從年初到現(xiàn)在,生成式 AI 發(fā)展迅猛。但很多時候,我們又不得不面臨一個難題:如何加快生成式 AI 的訓(xùn)練、推理等,尤其是在使用 PyTorch 的情況下。

本文 PyTorch 團隊的研究者為我們提供了一個解決方案。文章重點介紹了如何使用純原生 PyTorch 加速生成式 AI 模型,此外,文章還介紹了 PyTorch 新功能,以及如何組合這些功能的實際示例。

結(jié)果如何呢?PyTorch 團隊表示,他們重寫了 Meta 的「分割一切」 (SAM) 模型,從而使代碼比原始實現(xiàn)快 8 倍,并且沒有損失準確率,所有這些都是使用原生 PyTorch 進行優(yōu)化的。 

圖片

博客地址:https://pytorch.org/blog/accelerating-generative-ai/

看完本文,你將了解到:

  • Torch.compile:PyTorch 模型編譯器, PyTorch 2.0 加入了一個新的函數(shù),叫做 torch.compile (),能夠通過一行代碼對已有的模型進行加速;
  • GPU 量化:通過降低運算精度來加速模型;
  • SDPA(Scaled Dot Product Attention ):內(nèi)存高效的注意力實現(xiàn)方式;
  • 半結(jié)構(gòu)化 (2:4) 稀疏性:一種針對 GPU 優(yōu)化的稀疏內(nèi)存格式;
  • Nested Tensor:Nested Tensor 把 {tensor, mask} 打包在一起,將非均勻大小的數(shù)據(jù)批處理到單個張量中,例如不同大小的圖像;
  • Triton 自定義操作:使用 Triton Python DSL 編寫 GPU 操作,并通過自定義操作符注冊輕松將其集成到 PyTorch 的各種組件中。

圖片

PyTorch 原生特性所帶來的吞吐量增加以及減少的內(nèi)存開銷。

SAM 由 Meta 提出,關(guān)于這項研究的更多內(nèi)容請參考「CV 不存在了?Meta 發(fā)布「分割一切」AI 模型,CV 或迎來 GPT-3 時刻」。

圖片

接下來,文章介紹了 SAM 優(yōu)化過程,包括性能分析、瓶頸識別,以及如何將這些新功能整合進 PyTorch 以解決 SAM 面臨的這些問題。除此以外,本文還介紹了 PyTorch 的一些新特性:torch.compile、SDPA、Triton kernels、Nested Tensor 以及 semi-structured sparsity(半結(jié)構(gòu)化稀疏)。

本文內(nèi)容逐層深入,文章的最后會介紹快速版 SAM,感興趣的小伙伴可以去 GitHub 上下載,此外,本文還通過 Perfetto UI 對這些數(shù)據(jù)進行了可視化,以此來闡釋 PyTorch 每項特性的應(yīng)用價值。

GitHub 地址:https://github.com/pytorch-labs/segment-anything-fast

對分割一切模型 SAM 的重寫

該研究表示,本文利用的 SAM 基線數(shù)據(jù)類型為 float32 dtype、batch 大小為 1,使用 PyTorch Profiler 查看內(nèi)核跟蹤的結(jié)果如下:

圖片

本文發(fā)現(xiàn) SAM 有兩個地方可以優(yōu)化:

第一個是對 aten::index 的長調(diào)用,這是由張量索引操作(例如 [])產(chǎn)生的底層調(diào)用導(dǎo)致的。然而實際上 GPU 花費在 aten::index 上的時間相對較低,原因在于 aten::index 在啟動兩個內(nèi)核的過程中,兩者之間發(fā)生了阻塞 cudaStreamSynchronize。這意味著 CPU 會等待 GPU 完成處理,直到啟動第二個內(nèi)核。因而為了優(yōu)化 SAM,本文認為應(yīng)該致力于消除導(dǎo)致空閑時間的阻塞 GPU 同步。

第二個是 SAM 在矩陣乘法中花費了大量的 GPU 時間(上圖中的深綠色),這在 Transformers 中很常見。如果能夠減少 SAM 模型在矩陣乘法上花費的 GPU 時間,我們就可以顯著加快 SAM 的速度。

接下來本文用 SAM 的吞吐量 (img/s) 和內(nèi)存開銷 (GiB) 來建立基線。之后就是優(yōu)化過程了。

圖片

Bfloat16 半精度(加上 GPU 同步和批處理)

為了解決上述問題,即讓矩陣乘法花費的時間更少,本文轉(zhuǎn)向 bfloat16。Bfloat16 是常用的半精度類型,通過降低每個參數(shù)和激活的精度,能夠節(jié)省大量的計算時間和內(nèi)存。

圖片


用 bfloat16 替換 padding 類型

此外,為了移除 GPU 同步,本文發(fā)現(xiàn)有兩個位置可以優(yōu)化。

圖片


圖片

具體來說(參考上圖更容易理解,出現(xiàn)的變量名都在代碼中),該研究發(fā)現(xiàn)在 SAM 的圖像編碼器中,有充當(dāng)坐標(biāo)縮放器(coordinate scalers)的變量 q_coords 和 k_coords,這些變量都是在 CPU 上分配和處理的。然而,一旦這些變量被用來在 rel_pos_resized 中建立索引,這些索引操作就會自動的將這些變量移動到 GPU 上,這種復(fù)制會導(dǎo)致 GPU 同步。為了解決上述問題,該研究注意到可以使用 torch.where 重寫這部分內(nèi)容來解決問題,如上所示。

內(nèi)核跟蹤

在應(yīng)用了這些更改之后,本文注意到單個內(nèi)核調(diào)用之間有著顯著的時間間隔,尤其在小批量(這里為 1)時更為突出。為了更深入的了解這一現(xiàn)象,本文開始對批大小為 8 的 SAM 推理進行性能分析:

圖片

在查看每個內(nèi)核所花費的時間時,本文觀察到 SAM 的大部分 GPU 時間都花費在逐元素內(nèi)核(elementwise kernels)和 softmax 操作上。

現(xiàn)在可以看到矩陣乘法的相對開銷小了很多。

圖片

將 GPU 同步和 bfloat16 優(yōu)化結(jié)合在一起,SAM 性能提高了 3 倍。

圖片

Torch.compile(+graph breaks 和 CUDA graphs)

本文發(fā)現(xiàn)在深入研究 SAM 的過程中有很多小的操作,他們認為使用編譯器來融合操作有很大的好處,因而 PyTorch 對 torch.compile 做了以下優(yōu)化:

  • 將 nn.LayerNorm 或 nn.GELU 等操作序列融合成一個單一的 GPU 內(nèi)核;
  • 融合緊跟在矩陣乘法內(nèi)核之后的操作,以減少 GPU 內(nèi)核調(diào)用的數(shù)量。

通過這些優(yōu)化,該研究減少了 GPU 全局內(nèi)存往返次數(shù)(roundtrips),從而加快了推理速度。我們現(xiàn)在可以在 SAM 的圖像編碼器上嘗試 torch.compile。為了最大限度地提高性能,本文使用了一些高級編譯技術(shù):

圖片

內(nèi)核跟蹤

圖片

結(jié)果顯示,torch.compile 工作得很好。 

圖片

可以觀察到 softmax 占了很大一部分時間,然后是各種 GEMM 變體。以下測量的是批大小為 8 及以上的變化。

圖片

SDPA: scaled_dot_product_attention

接下來,本文又對 SDPA(scaled_dot_product_attention)進行了實驗,研究的重點是注意力機制。一般來講,原生注意力機制在時間和內(nèi)存上隨序列長度呈二次方擴展。PyTorch 的 SDPA 操作基于 Flash Attention、FlashAttentionV2 和 xFormer 的內(nèi)存高效注意力原理構(gòu)建,可以顯著加快 GPU 注意力。與 torch.compile 相結(jié)合,這個操作允許在 MultiheadAttention 的變體中表達和融合一個共同的模式。經(jīng)過一小部分更改后,現(xiàn)在模型可以使用 scaled_dot_product_attention。

圖片

內(nèi)核跟蹤

現(xiàn)在可以看到內(nèi)存高效的注意力內(nèi)核占用了 GPU 上大量的計算時間:

圖片

使用 PyTorch 的原生 scaled_dot_product_attention,可以顯著增加批處理大小。下圖為批大小為 32 及以上的變化。

圖片

之后,該研究又實驗了 Triton,NestedTensor 、批處理 Predict_torch, int8 量化,半結(jié)構(gòu)化 (2:4) 稀疏性等操作。

例如本文使用自定義 positional Triton 內(nèi)核,觀察到批大小為 32 的測量結(jié)果。

圖片

使用 Nested Tensor,批大小為 32 及以上的變化。

圖片

添加量化后,批大小為 32 及以上變化的測量結(jié)果。

圖片

文章的最后是半結(jié)構(gòu)化稀疏性。該研究表示,矩陣乘法仍然是需要面對的一個瓶頸。解決的辦法是使用稀疏化來近似矩陣乘法。通過稀疏矩陣(即將值歸零)可以使用更少的位來存儲權(quán)重和激活張量。該研究將張量中哪些權(quán)重設(shè)置為零的過程稱為剪枝。剪枝掉較小的權(quán)重可以潛在地減小模型大小,而不會顯著損失準確率。

剪枝的方法多種多樣,從完全非結(jié)構(gòu)化到高度結(jié)構(gòu)化。雖然非結(jié)構(gòu)化剪枝理論上對精度的影響最小,但 GPU 在進行大型密集矩陣乘法方面盡管非常高效,然而在稀疏情況下可能還會遭受顯著的性能下降。PyTorch 最近支持的一種剪枝方法旨在尋求平衡,稱為半結(jié)構(gòu)化(或 2:4)稀疏性。這種稀疏存儲將原始張量減少了 50%,同時產(chǎn)生密集張量輸出。參見下圖的說明。

圖片

為了使用這種稀疏存儲格式和相關(guān)的快速內(nèi)核,接下來要做的是剪枝權(quán)重。本文在 2:4 的稀疏度下選擇最小的兩個權(quán)重進行剪枝,將權(quán)重從默認的 PyTorch(“strided”)布局更改為這種新的半結(jié)構(gòu)化稀疏布局很容易。要實現(xiàn) apply_sparse (model),只需要 32 行 Python 代碼:

圖片

在 2:4 的稀疏度下,本文觀察到 vit_b 和批大小為 32 時的 SAM 峰值性能:

圖片

最后,一句話總結(jié)這篇文章:本文介紹了迄今為止在 PyTorch 上最快的 Segment Anything 實現(xiàn)方式,借助官方發(fā)布的一系列新功能,本文在純 PyTorch 中重寫了原始 SAM,并且沒有損失準確率。

感興趣的讀者可以查看原博客了解更多內(nèi)容。

責(zé)任編輯:張燕妮 來源: 機器之心
相關(guān)推薦

2023-04-25 11:36:17

CV模型

2023-06-27 17:35:39

FastSAM模型SAM

2024-07-30 10:51:51

2023-08-09 17:38:47

模型AI

2023-04-10 15:52:57

模型樣本

2023-05-04 12:19:47

模型AI

2023-04-23 15:42:18

圖像視頻

2023-07-17 13:14:45

模型分割

2023-12-07 07:16:57

Meta訓(xùn)練

2023-04-27 09:27:44

視頻AI

2023-05-26 10:15:34

模型訓(xùn)練

2023-12-06 13:36:00

模型數(shù)據(jù)

2024-03-01 10:04:11

研究訓(xùn)練編碼器

2025-03-27 09:47:23

訓(xùn)練模型AI

2022-10-27 08:31:31

架構(gòu)

2025-04-11 09:15:00

語言模型AI數(shù)據(jù)

2016-08-31 17:24:05

大數(shù)據(jù)分析

2012-12-31 11:22:58

開源開放

2025-03-20 07:20:00

2020-09-11 10:55:10

useState組件前端
點贊
收藏

51CTO技術(shù)棧公眾號