重複你自己*

釋出於 2022 年 4 月 5 日
在 GitHub 上更新
為現代機器學習設計開源庫

🤗 Transformers 設計理念

“別重複你自己”"Don't repeat yourself"),或稱 DRY,是軟體開發中一個眾所周知的原則。該原則源自於程式碼設計領域最受歡迎的書籍之一《程式設計師修煉之道》。這個原則傳達的資訊簡單明瞭:不要重寫已經存在於別處的邏輯。這能確保程式碼保持同步,使其更易於維護且更加健壯。對該邏輯模式的任何更改都將統一影響其所有依賴項。

乍一看,Hugging Face Transformers 庫的設計似乎與 DRY 原則背道而馳。注意力機制的程式碼被或多或少地複製了 50 多次到不同的模型檔案中。有時,整個 BERT 模型的程式碼也會被複制到其他模型檔案中。我們經常強制要求新的模型貢獻,即使它們與現有模型幾乎完全相同——除了一個微小的邏輯調整——也要複製所有現有程式碼。我們為什麼要這樣做?難道我們只是太懶或忙不過來,無法將所有邏輯部分集中到一個地方嗎?

不,我們並非懶惰——不將 DRY 設計原則應用於 Transformers 庫是一個非常審慎的決定。相反,我們決定採用一種不同的設計原則,我們稱之為 單一模型檔案 策略。單一模型檔案 策略規定,模型前向傳播所需的所有程式碼都位於且僅位於一個檔案中——稱為模型檔案。如果讀者想了解 BERT 在推理時如何工作,她應該只需要檢視 BERT 的 modeling_bert.py 檔案。我們通常會拒絕任何將不同模型的相同子元件抽象到一個新的中心化位置的嘗試。我們不希望有一個包含所有可能注意力機制的 attention_layer.py 檔案。那麼,我們為什麼要這樣做呢?

簡而言之,原因是:

  • 1. Transformers 是由開源社群構建,併為開源社群服務的。
  • 2. 我們的產品是模型,我們的客戶是閱讀或調整模型程式碼的使用者。
  • 3. 機器學習領域的發展速度極快。
  • 4. 機器學習模型是靜態的。

1. 由開源社群構建,併為開源社群服務

Transformers 的構建旨在積極鼓勵外部貢獻。貢獻通常是 bug 修復或新模型貢獻。如果在某個模型檔案中發現了一個 bug,我們希望讓發現者儘可能容易地修復它。沒有什麼比修復一個 bug 後發現它導致了其他 100 個模型的失敗更令人沮喪的了。

因為模型程式碼獨立於所有其他模型,所以對於只瞭解自己正在使用的那個模型的人來說,修復它相當容易。同樣,如果只需新增一個新模型檔案,新增新的建模程式碼和審查相應的 PR 也會更容易。貢獻者不必費心去思考如何在不破壞現有模型的情況下向中心化的注意力機制新增新功能。審查者可以輕鬆驗證所有現有模型都沒有被破壞。

2. 建模程式碼是我們的產品

我們假設,Transformers 庫的大量使用者不僅會閱讀文件,還會檢視實際的建模程式碼並可能對其進行修改。這一假設得到了 Transformers 庫被 fork 超過 10,000 次以及 Transformers 論文被引用超過一千次的佐證。因此,讓首次閱讀 Transformers 建模程式碼的人能夠輕鬆理解並可能進行修改至關重要。在一個單一的建模檔案中按順序提供所有必要的邏輯元件,極大地有助於提高可讀性和適應性。此外,我們非常注重合理的變數/方法命名,並傾向於使用表達力強/可讀性高的程式碼,而非字元高效的程式碼。

3. 機器學習正以前所未有的速度發展

機器學習領域,尤其是神經網路的研究,發展速度極快。一年前還是最先進的模型,今天可能就已經過時了。我們不知道一年後哪種注意力機制、位置嵌入或架構會是最好的。因此,我們無法定義適用於所有模型的標準邏輯模式。

舉個例子,兩年前,人們可能會將 BERT 的自注意力層定義為所有 Transformers 模型使用的標準注意力層。從邏輯上講,一個“標準”的注意力函式可以被移到一箇中心的 attention.py 檔案中。但隨後出現了在每個注意力層中新增相對位置嵌入的注意力層(T5),多種不同形式的分塊注意力(Reformer, Longformer, BigBird),以及用於位置和詞嵌入的獨立注意力機制(DeBERTa),等等……每一次我們都不得不問自己,是否應該調整“標準”的注意力函式,或者是否最好在 attention.py 中新增一個新的注意力函式。但那時我們該如何命名呢?attention_with_positional_embd, reformer_attention, deberta_attention

給機器學習模型的邏輯元件起通用名稱是危險的,因為人們對這個元件所代表的含義的看法可能會很快改變或過時。例如,分塊注意力是指 GPTNeo、Reformer 還是 BigBird 的分塊注意力?注意力層是自注意力層、交叉注意力層,還是兩者都包括?然而,如果我們用模型的名稱來命名注意力層,我們就應該直接將注意力函式放在相應的建模檔案中。

4. 機器學習模型是靜態的

Transformers 庫是不同研究團隊建立的機器學習模型的統一且精煉的集合。每個機器學習模型通常都附有一篇論文及其官方 GitHub 倉庫。一旦一個機器學習模型被髮布,之後就很少再被修改或改變。

相反,研究團隊傾向於在先前模型的基礎上釋出新模型,但很少對已釋出的程式碼進行重大更改。這是在決定 Transformers 庫的設計原則時的一個重要認識。這意味著一旦一個模型架構被新增到 Transformers,模型的基本元件就不會再改變了。Bug 經常被發現和修復,方法和變數可能會被重新命名,模型的輸出或輸入格式可能會有輕微改變,但模型的核心元件不會再改變。因此,對 Transformers 中所有模型進行全域性更改的需求大大減少,這使得每個邏輯模式只存在一次變得不那麼重要,因為它很少被改變。

第二個認識是,模型之間並 存在雙向依賴。較新發布的模型可能依賴於現有模型,但很明顯,現有模型在邏輯上不可能依賴於其後繼者。例如,T5 部分基於 BERT 構建,因此 T5 的建模程式碼在邏輯上可能依賴於 BERT 的建模程式碼,但 BERT 在任何方面都不可能邏輯上依賴於 T5。因此,重構 BERT 的注意力函式以使其也能與 T5 的注意力函式一起工作在邏輯上是不合理的——閱讀 BERT 注意力層的人不應該需要知道任何關於 T5 的資訊。這再次表明,不應將注意力層等元件集中到所有模型都可以訪問的模組中。

另一方面,後繼模型的建模程式碼很可能在邏輯上依賴於其前身模型。例如,DeBERTa-v2 的建模程式碼在某種程度上確實邏輯上依賴於 DeBERTa 的建模程式碼。透過確保 DeBERTa-v2 的建模程式碼與 DeBERTa 的保持同步,可維護性得到了顯著提高。修復 DeBERTa 中的一個 bug 理想情況下也應該修復 DeBERTa-v2 中的同一個 bug。我們如何能在維持 單一模型檔案 策略的同時,確保後繼模型與其前身模型保持同步呢?

現在,我們來解釋為什麼我們在 “重複你自己” 後面加上了星號 * {}^{\textbf{*}} 。我們不會盲目地複製貼上所有現有的建模程式碼,即使看起來是這樣。Transformers 的一位核心維護者 Sylvain Gugger 發現了一個很好的機制,它既尊重了 單一檔案策略,又將維護成本控制在合理範圍內。這個機制,我們非正式地稱之為 “複製機制”,允許我們用一個 # Copied from <predecessor_model>.<function> 語句來標記邏輯元件,比如一個注意力層函式,這會強制被標記的程式碼與 <predecessor_model><function> 完全相同。例如,DeBERTa-v2 類 的這一行程式碼強制整個類與 DeBERTa 的類 相同,除了字首 DeBERTav2。透過這種方式,複製機制使得建模程式碼非常容易理解,同時顯著降低了維護成本。如果一個前身模型的函式中的某些程式碼被更改,而其後繼模型的函式引用了它,那麼會有工具自動修正後繼模型的函式。

缺點

顯然,單一檔案策略也有其缺點,我們想在這裡快速提及其中兩個。

Transformers 的一個主要目標是為所有模型提供統一的推理和訓練 API,以便使用者可以在其設定中快速切換不同的模型。然而,如果建模檔案不允許使用抽象的邏輯模式,那麼確保跨模型 API 的統一性就會困難得多。我們透過執行 大量 測試(在撰寫這篇博文時,每天大約執行 20,000 個測試)來解決這個問題,以確保模型遵循一致的 API。在這種情況下,單一檔案策略要求我們在審查模型和測試新增時非常嚴格。

其次,有很多研究僅僅針對機器學習模型的一個元件。例如,研究團隊會研究新形式的注意力機制,這些機制可以應用於所有現有的預訓練模型,就像在 《用 Performers 重新思考注意力》 中所做的那樣。我們應該如何將這類研究整合到 Transformers 庫中呢?這確實是個問題。我們應該修改所有現有的模型嗎?這與上面寫的第 3 點和第 4 點相悖。我們應該新增 100 多個以 Performer... 為字首的新建模檔案嗎?這似乎很荒謬。在這種情況下,遺憾的是沒有好的解決方案,我們選擇不將該論文整合到 Transformers 中。如果該論文獲得了更大的關注度幷包含了強大的預訓練檢查點,我們可能會新增一些最重要模型的新建模檔案,例如 modeling_performer_bert.py

結論

總而言之,在 🤗 Hugging Face,我們堅信 單一檔案策略 是 Transformers 正確的編碼理念。

您怎麼看?如果您讀到了這裡,我們非常想聽聽您的意見!如果您想留言,請訪問相應的論壇帖子 這裡

社群

註冊登入 發表評論

© . This site is unofficial and not affiliated with Hugging Face, Inc.