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

相同的 LLM 在「不同 GPU 上」會(huì)產(chǎn)生不同輸出?為什么? 原創(chuàng)

發(fā)布于 2024-8-9 09:44
瀏覽
0收藏

編者按: 在大語言模型(LLMs)的部署及其相關(guān)的算力擴(kuò)容過程中,更換 GPU 是否也可能會(huì)對(duì)模型的輸出產(chǎn)生重大影響?這個(gè)問題的答案對(duì)于確保 LLMs 在不同硬件環(huán)境下的一致性和可靠性至關(guān)重要。

我們今天為大家?guī)淼倪@篇文章,作者的核心觀點(diǎn)是:即使在相同的開發(fā)環(huán)境、系統(tǒng)配置和隨機(jī)種子下,不同的 GPU 也會(huì)導(dǎo)致 LLMs 產(chǎn)生不同的模型輸出。

作者通過實(shí)驗(yàn)證明,在使用 Nvidia Tesla T4 和 Nvidia A10G 兩種不同 GPU 的情況下,Mistral-7b-v0.1 模型對(duì)相同的輸入產(chǎn)生了不同的輸出。這種差異主要源于 GPU 在并行計(jì)算處理、硬件架構(gòu)和模型量化的影響等方面的不同。隨著提示詞長度的增加,這種不準(zhǔn)確性會(huì)被放大,因?yàn)楦L的提示詞需要進(jìn)行更多計(jì)算,從而加劇了不準(zhǔn)確性的傳播。在使用多個(gè) GPU 擴(kuò)展時(shí),如果采用模型分片策略,理論上可能會(huì)因計(jì)算分布的不同而導(dǎo)致結(jié)果產(chǎn)生變化,但實(shí)踐中 PyTorch 的設(shè)計(jì)似乎保證了結(jié)果的一致性。

作者 | Anis Zakari

編譯 | 岳揚(yáng)

大多數(shù)技術(shù)工程師都了解,依賴庫或依賴組件的版本不同都可能會(huì)導(dǎo)致系統(tǒng)行為產(chǎn)生變化。但在大語言模型(Large Language Models)領(lǐng)域,由于算力需求巨大,在訓(xùn)練和推理任務(wù)中我們都極度依賴 GPU。然而,很少有人真正意識(shí)到,更換 GPU 也會(huì)對(duì) LLMs 的輸出產(chǎn)生影響。

假如你想創(chuàng)建兩個(gè)完全一致的開發(fā)環(huán)境:

  • 可以指定依賴庫或組件的版本。
  • 可以使用 Dockerization。
  • 可以將 LLMs 的 temperature 設(shè)置為 0。
  • 可以選擇任意的隨機(jī)種子。 但是,如果使用的不是完全相同的 GPU 型號(hào),以上所有努力都將白費(fèi)。

本文將進(jìn)行一次實(shí)驗(yàn)來強(qiáng)調(diào)這一現(xiàn)象,說明差異出現(xiàn)的位置及其原因。

Note:如果對(duì)實(shí)驗(yàn)過程的重現(xiàn)或具體代碼不感興趣,可以跳過本文展示代碼片段,直接閱讀“7. 為什么同樣的 inputs 和同樣的 LLMs 在兩塊不同 GPU 上生成的模型響應(yīng)會(huì)有如此大的差別?”這部分內(nèi)容。即便不看前面的代碼片段,Conclusion 部分仍然有助于我們理解其中的原理。

01 為什么要寫這篇文章?

有一天,我和一些人討論為什么 OpenAI 和 Anthropic 的那些模型在設(shè)計(jì)時(shí)沒有被構(gòu)建為確定性的系統(tǒng)。我解釋說,它們可能采用了混合專家模型(Mixture of Experts, MoE)方法<sup>[1]</sup>,偶爾不會(huì)將 tokens 路由給最優(yōu)的專家模型,因?yàn)檫@些專家模型可能正忙于處理其他 tokens,所以可能會(huì)導(dǎo)致模型響應(yīng)的不一致。

另一個(gè)因素可能是 OpenAI 為了提高效率而對(duì) queries 進(jìn)行了批量處理。batches size 會(huì)根據(jù)傳入的 queries 數(shù)量而變化,可能會(huì)改變 GPU 的計(jì)算策略,從而導(dǎo)致不同的模型響應(yīng)。

當(dāng)有人指出,“不同的 GPU 也可能導(dǎo)致出現(xiàn)不同的模型響應(yīng),不是嗎?”時(shí),我們之間的對(duì)話開始變得耐人尋味起來了。

仔細(xì)想一想……當(dāng)我們使用 OpenAI API 時(shí),實(shí)際上是有一臺(tái)遠(yuǎn)程服務(wù)器幫我們執(zhí)行計(jì)算并返回模型響應(yīng)?,F(xiàn)在,如果這臺(tái)機(jī)器并非總是在相同的算力基礎(chǔ)設(shè)施上運(yùn)行,那么最終得到的模型響應(yīng)就不會(huì)相同。

想到這一點(diǎn),可能就會(huì)出現(xiàn)其他問題:

  • 如果有一個(gè)在生產(chǎn)開發(fā)環(huán)境中運(yùn)行的 LLM app,并且需要將其擴(kuò)展到擁有不同 GPU 的其他實(shí)例,是否會(huì)出現(xiàn)很嚴(yán)重的問題?
  • 如果開發(fā)環(huán)境(development environment)中的 GPU 與生產(chǎn)環(huán)境(production environment)存在大量不同之處,會(huì)怎么樣?

這些問題促使我想設(shè)置一個(gè)實(shí)驗(yàn)來突出這一現(xiàn)象,并探究它可能造成的影響有多大。

02 配置實(shí)驗(yàn)環(huán)境

為了突出這一現(xiàn)象,我將設(shè)置兩個(gè)完全相同的開發(fā)環(huán)境,它們唯一的區(qū)別在于其所使用的 GPU:第一個(gè)開發(fā)環(huán)境中使用的是 Nvidia Tesla T4,第二個(gè)開發(fā)環(huán)境使用的便是 Nvidia A10G。然后,我們將使用 Mistral-7b-v0.1 進(jìn)行測試,看看會(huì)發(fā)生什么。

要在 notebook 中運(yùn)行實(shí)驗(yàn),請(qǐng)按照以下步驟操作。

2.1 配置開發(fā)環(huán)境(Setup the environment)

1. 配置 CUDA 版本

相同的 LLM 在「不同 GPU 上」會(huì)產(chǎn)生不同輸出?為什么?-AI.x社區(qū)

2. 配置 transformers 和其他依賴

相同的 LLM 在「不同 GPU 上」會(huì)產(chǎn)生不同輸出?為什么?-AI.x社區(qū)

3. 設(shè)置隨機(jī)種子(random seeds)

相同的 LLM 在「不同 GPU 上」會(huì)產(chǎn)生不同輸出?為什么?-AI.x社區(qū)

注釋 1:

僅設(shè)置 transformers.set_seed 應(yīng)該就足夠了,但我還是想要確保萬無一失。

注釋 2:

本例使用的是 Python 3.10。

2.2 加載 Mistral 模型

要從 Hugging Face 中加載 Mistral-7B-v0.1 模型,我們需要在環(huán)境變量 HF_TOKEN 中設(shè)置 Hugging Face tokens。

本文將會(huì)使用量化版本的模型,降低計(jì)算精度來減少 GPU 的內(nèi)存占用。

相同的 LLM 在「不同 GPU 上」會(huì)產(chǎn)生不同輸出?為什么?-AI.x社區(qū)

2.3 使用 transformers 庫中的 pipeline

我們將使用 transformers 庫中的 pipeline 來簡化從大語言模型(LLMs)生成模型響應(yīng)的過程。

為了確保模型輸出是可預(yù)測和一致的,我們希望從大語言模型的 vocabulary 中持續(xù)預(yù)測出最有可能的 tokens,因此我們可以將 top_k 設(shè)置為 1 或?qū)?temperature 設(shè)置為接近 0 的值。

此外,為了簡單起見,我們將把 max_new_tokens 參數(shù)設(shè)置為 1,這樣 LLMs 就能只用單個(gè) token 完成提示詞。

相同的 LLM 在「不同 GPU 上」會(huì)產(chǎn)生不同輸出?為什么?-AI.x社區(qū)

當(dāng)給出提示詞序列 “I enjoy walking in the” 時(shí),大語言模型(LLMs)只會(huì)生成一個(gè)單詞:“woods”。如果大語言模型(LLMs)正確地生成并輸出了這個(gè)單詞,我們就可以繼續(xù)進(jìn)行實(shí)驗(yàn)了。

03 實(shí)驗(yàn)結(jié)果:T4 vs A10G

為了能夠使用這兩塊 GPU,我通過 AWS SageMaker 啟動(dòng)了 ml.g4dn.xlarge (T4) 和 ml.g5.xlarge (A10G) 實(shí)例。

讓我們嘗試運(yùn)行一個(gè)簡單的 query :

相同的 LLM 在「不同 GPU 上」會(huì)產(chǎn)生不同輸出?為什么?-AI.x社區(qū)

相同的 LLM 在「不同 GPU 上」會(huì)產(chǎn)生不同輸出?為什么?-AI.x社區(qū)

T4 和 A10G 給我的模型響應(yīng)是一樣的:

相同的 LLM 在「不同 GPU 上」會(huì)產(chǎn)生不同輸出?為什么?-AI.x社區(qū)

到目前為止一切進(jìn)展順利。不過,這只是一個(gè)簡短的 query 。在 RAG(檢索增強(qiáng)生成)的應(yīng)用場景里,我們通常會(huì)處理成千上萬個(gè) tokens ?,F(xiàn)在讓我們使用在 Hugging Face 上托管的 llama-2-arxiv-papers-chunked 數(shù)據(jù)集來進(jìn)行更大規(guī)模的 query 測試。

在下面的代碼示例中,我將模仿 RAG 的工作方式,使用數(shù)據(jù)集索引 0、4518、4519 和 799 處獲取的文本片段。其中第 4518 和 4519 個(gè)數(shù)據(jù)塊(chunks)討論了 “Llama 2”,而其他片段則沒有提及。我們期待 LLMs 能基于這些上下文信息回答:“Llama 2 有什么特別之處?”該提示詞大概有 1,400 個(gè) tokens 長。

相同的 LLM 在「不同 GPU 上」會(huì)產(chǎn)生不同輸出?為什么?-AI.x社區(qū)

T4 模型的輸出如下:

相同的 LLM 在「不同 GPU 上」會(huì)產(chǎn)生不同輸出?為什么?-AI.x社區(qū)

A10G 模型的輸出如下:

相同的 LLM 在「不同 GPU 上」會(huì)產(chǎn)生不同輸出?為什么?-AI.x社區(qū)

確實(shí)很有趣。乍一看,由于兩個(gè)模型響應(yīng)開頭相同,區(qū)別卻不太明顯。但在“等等(etc)……”之后,兩者就有所差異了。

T4 模型輸出如下:“etc… This also means you can trust the output more since everything inside will be consistent across different runs!…”

A10G 模型輸出如下:“etc… This also means you can be more confident when asking questions specifically related to topics covered within those texts…”

04 T4 Colab vs T4 SageMaker

想知道使用相同 GPU 的兩個(gè)開發(fā)環(huán)境是否會(huì)產(chǎn)生相同的模型輸出?我進(jìn)行了一系列測試,結(jié)果確實(shí)完全相同。

05 為什么相同的用戶輸入(inputs)和相同的 LLMs 在兩個(gè) GPUs 上生成的答案會(huì)如此不同?

最終,這些模型響應(yīng)因?yàn)?LLMs 的自回歸特性而變得截然不同。由于下一個(gè) token 是根據(jù)之前的 tokens 選擇的,任何細(xì)微的變化都會(huì)引發(fā)一連串的連鎖反應(yīng),就像蝴蝶效應(yīng)(butterfly effect)一樣。

請(qǐng)注意,這些模型響應(yīng)并沒有像提示詞中所要求的那樣基于所提供的上下文。LLMs 并沒有完全遵循指導(dǎo)性提示詞(instructions),但這并不是很重要。

因?yàn)槲覀兗僭O(shè) LLMs 總是基于前面的 tokens 選擇概率(probabilities)最高的 token,所以我們可以肯定,區(qū)別在于如何在 GPU 上計(jì)算該概率(probabilities),下面讓我們來看一看如何計(jì)算該概率~

06 計(jì)算 tokens 的選擇概率(probabilities)

為了打印出每個(gè)被選中 token 的概率,我們將繞過常規(guī)處理流程(pipeline),直接使用 tokenizer 和 model.generate 方法。這樣我們就能設(shè)置 return_dict_in_generate=Trueoutput_scores=True。接著,我們就可以進(jìn)行計(jì)算(compute)操作、對(duì)其進(jìn)行歸一化操作(normalize),并將 transition scores(譯者注:在自然語言處理領(lǐng)域,尤其是使用自回歸模型生成文本時(shí),模型會(huì)為每個(gè) next token 分配一個(gè)概率分?jǐn)?shù),這個(gè)分?jǐn)?shù)反映了該 token 作為 tokens 序列中 next token 的可能性大小。) 轉(zhuǎn)換為概率(probabilities)。

相同的 LLM 在「不同 GPU 上」會(huì)產(chǎn)生不同輸出?為什么?-AI.x社區(qū)

上述代碼會(huì)顯示每個(gè) token 的 ID、解碼后的 token 以及其對(duì)應(yīng)的概率(probability)。此處我只列出相關(guān)的模型輸出內(nèi)容,因?yàn)橥暾膬?nèi)容非常長。

T4 Output:

相同的 LLM 在「不同 GPU 上」會(huì)產(chǎn)生不同輸出?為什么?-AI.x社區(qū)

A10G Output:

相同的 LLM 在「不同 GPU 上」會(huì)產(chǎn)生不同輸出?為什么?-AI.x社區(qū)

好了,現(xiàn)在事情變得越來越有趣了。T4 和 A10G 上的概率值(probabilities)并不完全一致。一般情況下,這樣并不會(huì)影響 tokens 的排序序列(無法在生成的 tokens 序列中察覺到任何不同),但有時(shí)候確實(shí)會(huì)造成影響。

例如,在 T4 模型中,“trust” 出現(xiàn)的概率為 18.74 %,而在 A10G 上,“be” 出現(xiàn)的概率則更高,達(dá)到了 18.62 %。從這一點(diǎn)來看,由于大語言模型的自回歸特性,生成的內(nèi)容將會(huì)出現(xiàn)偏差(diverge)。

注釋:量化大語言模型會(huì)降低計(jì)算精度(calculation precision),導(dǎo)致這類差異變得更為常見。

現(xiàn)在,一個(gè)非常合理的問題就出現(xiàn)了:“為什么計(jì)算結(jié)果會(huì)因?yàn)?GPU 的不同而產(chǎn)生差異呢?”

07 為什么 GPU 不同,模型運(yùn)算結(jié)果也不同?

雖然我不是 CUDA expert(譯者注:這類人能夠熟練使用 CUDA C/C++ 編程語言來開發(fā)高性能的并行計(jì)算應(yīng)用,并了解如何優(yōu)化 GPU 上的計(jì)算任務(wù)來獲得最佳性能。),但我進(jìn)行過一些研究。不同 GPU 之間的計(jì)算差異可以歸因于以下幾個(gè)因素:

并行計(jì)算處理(Parallel Computation Handling):

GPUs 的特點(diǎn)是能夠高效地并行處理大量的計(jì)算任務(wù)。然而,不同 GPU 在管理這些并行任務(wù)時(shí)可能會(huì)有所差異,從而影響到運(yùn)算順序以及內(nèi)存的訪問方式。

這一點(diǎn)非常重要,因?yàn)樵诰幊踢^程中,即使是數(shù)值大小相差很大的簡單加法也可能是 non-associative,從而影響到精確計(jì)算(precise calculations)的準(zhǔn)確性。所謂 “Non-associativity” 是指:(a + b) + c ≠ a + (b + c)。

相同的 LLM 在「不同 GPU 上」會(huì)產(chǎn)生不同輸出?為什么?-AI.x社區(qū)

因此,計(jì)算任務(wù)會(huì)被分割開來,獨(dú)立進(jìn)行處理,然后以 non-associative 方式組合在一起。因此,這些部分的內(nèi)容如何重新組合會(huì)影響到最終結(jié)果。

這里有一個(gè)關(guān)于 non-associative computation 的簡單示例:

相同的 LLM 在「不同 GPU 上」會(huì)產(chǎn)生不同輸出?為什么?-AI.x社區(qū)

對(duì)于大語言模型(LLMs),數(shù)百萬次的計(jì)算可能會(huì)因?yàn)橹貜?fù)出現(xiàn)的微小誤差而導(dǎo)致出現(xiàn)偏差(diverge),進(jìn)而影響到序列生成過程中的字詞選擇。

硬件架構(gòu)(Hardware Architecture):

不同型號(hào)的 GPU,如 Nvidia Tesla T4 和 Nvidia A10G ,具備不同的硬件架構(gòu)。這些硬件架構(gòu)能夠優(yōu)化模型各個(gè)方面的性能,包括并行處理能力(parallel processing capabilities)、內(nèi)存帶寬(memory bandwidth)和計(jì)算單元(compute units)。

例如,T4 模型采用了 Turing<sup>[2]</sup> 架構(gòu),而 A10G 模型基于 Ampere<sup>[3]</sup> 架構(gòu)。

不同的模型架構(gòu)意味著在浮點(diǎn)運(yùn)算(floating-point arithmetic)、內(nèi)存訪問模式(memory access patterns)和其他底層操作上有著不同的實(shí)現(xiàn)方式。即使這些實(shí)現(xiàn)方式(implementations)存在細(xì)微差別,也可能會(huì)導(dǎo)致計(jì)算結(jié)果出現(xiàn)差異。

例如,與針對(duì)更高計(jì)算精度而進(jìn)行優(yōu)化的模型架構(gòu)相比,為了計(jì)算速度而優(yōu)化的模型架構(gòu)可能會(huì)產(chǎn)生不同的模型響應(yīng),即便兩者都在執(zhí)行相同的浮點(diǎn)運(yùn)算。

模型量化的影響(Quantization Effects):

通過模型量化(Quantizing)來降低計(jì)算精度可以節(jié)省內(nèi)存資源和計(jì)算資源,但這樣做也會(huì)引入額外的誤差源(sources of error)。這些誤差的影響因 GPU 對(duì)低精度運(yùn)算(lower precision arithmetic)的處理方式不同而不同。

由于模型量化(quantization)過程中涉及到對(duì)數(shù)值的近似處理,因此不同的 GPU 在處理這些近似值時(shí)可能會(huì)有所差異,從而最終會(huì)導(dǎo)致 token 的預(yù)測概率產(chǎn)生變化。

08 使用多個(gè) GPU 水平擴(kuò)展 LLMs 時(shí)需要注意什么?

這個(gè)問題問得非常好,非常感謝!: )

如果只是簡單地增加相同型號(hào)的 GPU 數(shù)量(例如,從單個(gè) A10G GPU 擴(kuò)展到擁有 4 個(gè) A10G GPU 的實(shí)例),是否還有必要擔(dān)心?

使用多個(gè) GPU 進(jìn)行推理時(shí),有幾種策略可供選擇:

  • 第一種策略是,如果模型可以裝入 GPU 中,可以在每個(gè) GPU 上加載一份模型副本。例如,如果向 pipeline 發(fā)送四條查詢語句(queries),每條查詢語句(queries)可以由不同的 GPU 來處理。這樣,我們將得到與僅使用一個(gè) GPU 時(shí)相同的輸出內(nèi)容,但吞吐量會(huì)有所提高。
  • 第二種策略通常用于因?yàn)槟P吞笠粋€(gè) GPU 無法裝入的情況,可以采用模型分片策略(sharding),將模型的權(quán)重分布到各個(gè) GPU 上。雖然從理論上講,這種做法可能會(huì)因?yàn)橛?jì)算(computation)的分布(distribution)和執(zhí)行(execution)的不同而導(dǎo)致模型響應(yīng)產(chǎn)生變化,但在實(shí)踐測試中,使用模型切片技術(shù)得到的序列(sequences)和概率(probabilities)與單個(gè) GPU 上得到的結(jié)果是一致的。我猜測這是因?yàn)?PyTorch 在設(shè)計(jì)時(shí)考慮到了 deterministic operations(譯者注:那些每次在相同輸入下都能產(chǎn)生相同輸出的操作過程。)。

09 Conclusion

我們已經(jīng)證明了,即便是相同的開發(fā)環(huán)境(environment)、系統(tǒng)配置(settings)和隨機(jī)種子(seed),不同的 GPU 也會(huì)導(dǎo)致 LLMs 產(chǎn)生不同的結(jié)果。隨著提示詞長度的增長,這種不準(zhǔn)確性(inaccuracies)也會(huì)隨之增加,因?yàn)楦L的提示詞需要更多的算力,這會(huì)加劇不準(zhǔn)確性(inaccuracies)的傳播并促進(jìn)兩個(gè) GPU 之間的差異。此外,在進(jìn)行模型量化的情況下,這種效應(yīng)更加顯著。

我并不是說這種情況一定是災(zāi)難性的,但這是我們?cè)谔幚?LLMs 的部署時(shí)需要注意的一個(gè)因素。

如果我們開發(fā)時(shí)使用的 GPU 與生產(chǎn)環(huán)境中使用的 GPU 不同,應(yīng)該設(shè)置測試實(shí)驗(yàn)確保性能仍然保持在可接受的范圍內(nèi)。如果我們計(jì)劃將 LLMs 擴(kuò)展到擁有不同 GPU 的新實(shí)例上,這一點(diǎn)也很重要。

如果你堅(jiān)持讀到了最后,那我可太高興了,希望你會(huì)喜歡這篇文章。如果你喜歡的話,希望你能給我點(diǎn)贊,鼓勵(lì)我繼續(xù)寫作,也歡迎在評(píng)論區(qū)中分享你的想法。


Anis Zakari

I’m a passionate ML/AI Engineer based in Paris. I am particularly interested in NLP, LLM, Software Engineering and Cloud Engineering subjects

文中鏈接

[1]https://standardscaler.com/2024/03/06/the-non-determinism-of-openai-and-anthropic-models/

[2]https://www.nvidia.com/fr-fr/geforce/turing/

[3]https://www.nvidia.com/fr-fr/data-center/ampere-architecture/

原文鏈接:

https://medium.com/@anis.zakari/changing-the-gpu-is-changing-the-behaviour-of-your-llm-0e6dd8dfaaae

?著作權(quán)歸作者所有,如需轉(zhuǎn)載,請(qǐng)注明出處,否則將追究法律責(zé)任
已于2024-8-22 10:24:46修改
收藏
回復(fù)
舉報(bào)
2條回復(fù)
按時(shí)間正序
/
按時(shí)間倒序
火鳳凰931
火鳳凰931

圖片沒有顯示,求更新

回復(fù)
2024-8-9 10:36:01
Baihai_IDP
Baihai_IDP 回復(fù)了 火鳳凰931
圖片沒有顯示,求更新

您好,我這邊顯示正常呀~

回復(fù)
2024-8-15 11:26:32
回復(fù)
相關(guān)推薦