大模型推理:
目前在項目中試驗了多種大模型:llama,vicuna,chatglm,ziya,baichuan泛烙,以及模型微調(diào)+模型推理【嗔荆總的來講目前在模型推理方面還有很大的優(yōu)化空間余佃,比如:因為沒有beam-search的緣故,流式輸出的效果不如直接輸出跨算。所以目前優(yōu)先考慮優(yōu)化模型推理方面的效果爆土。
transformer中對于推理的方式有以下這些,逐一了解下:
Greedy Search
“直接選概率最大的詞”稱為"Greedy Search"策略诸蚕,也就是在每個時間步t步势,總是選擇最高概率的詞作為下一個詞氧猬。
這個策略實現(xiàn)起來非常簡單,但是對應的缺點也很明顯:
- 第一坏瘩,因為每次只是選取概率最高的詞盅抚,因此生成的文本是完全確定的,即不具有任何多樣性倔矾,但是現(xiàn)實場景的需求泉哈,通常需要這種多樣性,例如客戶要求對一個給定商品破讨,生成10條不同的文案供他挑選。
- 第二奕纫,greedy search是一個貪心且短視的策略提陶,通常不是全局最優(yōu)的,例如在上圖中匹层,如果第二個詞選擇概率第二高的"dog"隙笆,而第三個詞選擇"has",則最終生成文本序列為"The dog has"升筏,對應的聯(lián)合概率為0.4*0.9=0.36撑柔,顯然好于greedy search生成的"The nice woman"。
在transformer庫中的generate方法默認使用的策略就是greedy search您访,調(diào)用時不傳任何參數(shù)即可铅忿,或者同時指定do_sample=False, num_beams=1
。示例代碼如下:
from transformers import AutoModelForCausalLM, AutoTokenizer
prompt = "I look forward to"
checkpoint = "distilgpt2"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
inputs = tokenizer(prompt, return_tensors="pt")
model = AutoModelForCausalLM.from_pretrained(checkpoint)
for _ in range(5):
outputs = model.generate(**inputs, do_sample=False, num_beams=1)
print(tokenizer.batch_decode(outputs, skip_special_tokens=True))
Beam Search
前面提到灵汪,greedy search是一個貪心且短視的策略檀训,而beam search就是針對這一點做出的改進策略。它的基本思想是:在每一個時間步t享言,都保留多個不同的候選結(jié)果峻凫,直到最后一步才確定到底哪一個候選結(jié)果更為占優(yōu)。候選結(jié)果的數(shù)量就是參數(shù)"num_beams"览露。
首先荧琼,第一個詞“The”是已經(jīng)確定的,在下一個詞差牛,我們并不只選擇當前概率最高的"nice"命锄,同時還要把概率次高的“dog“也記錄下作為候選結(jié)果,此時記錄的兩個候選結(jié)果為:
- (The, nice): 0.5
- (The, dog): 0.4
再接下來多糠,兩個候選結(jié)果再繼續(xù)選擇各自概率top2高的詞(因為“The nice house”和“The nice guy”同分累舷,“The dog runs”和“The dog and”同分夹孔,實際這里選的是top3高的詞)被盈,記錄為:
- (The, nice, woman): 0.5*0.4=0.2
- (The, nice, horse): 0.5*0.3=0.15
- (The, nice, guy): 0.5*0.3=0.15
- (The, dog, has): 0.4*0.9=0.36
- (The, dog, and): 0.4*0.05=0.02
- (The, dog, runs): 0.4*0.05=0.02
因為num_beams=2析孽,這里仍然只保留聯(lián)合概率top2的序列作為候選:
- (The, dog, has): 0.4*0.9=0.36
- (The, nice, woman): 0.5*0.4=0.2
如果還沒到終止條件,beam search會重復上述過程繼續(xù)執(zhí)行下去只怎,如果已經(jīng)到了最大長度袜瞬,則會選取當前分數(shù)最高的(The, dog, has)進行輸出。
顯然身堡,beam search生成過程中的計算量大于greedy search邓尤,且beam search生成的文本序列的概率至少不會低于greedy search,也就是效果一定不差于greedy search贴谎。但是要注意汞扎,beam search生成的序列仍然不保證概率上是全局最優(yōu)的!
在transformer庫中使用beam search擅这,需要指定do_sample=False且num_beams>1`澈魄。示例代碼如下:
from transformers import AutoModelForCausalLM, AutoTokenizer
prompt = "I look forward to"
checkpoint = "distilgpt2"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
inputs = tokenizer(prompt, return_tensors="pt")
model = AutoModelForCausalLM.from_pretrained(checkpoint)
for _ in range(5):
outputs = model.generate(**inputs, do_sample=False, num_beams=20)
print(tokenizer.batch_decode(outputs, skip_special_tokens=True))
Multinomial Sampling
目前為止的兩種解碼策略都只能生成確定性的結(jié)果,而Multinomial Sampling則是一種不確定的解碼策略仲翎,可以提供文本生成的多樣性痹扇。它的基本思想是:在生成下一個候選詞時,選定一個采樣范圍進行隨機采樣溯香,在采樣范圍的詞只要概率不為0鲫构,就有可能采樣到這個詞。在transformers庫中玫坛,只需要設置num_beams=1且do_sample=True结笨,就會進入Multinomial Sampling策略。
Top-K Sampling
Top-K Sampling的思路為:當要生成下一個詞的時候湿镀,只截斷選取概率最高的前K個詞禀梳,對這K個詞的概率重新進行歸一化,然后在其中進行采樣肠骆。 在transformers中使用Top-K Sampling的方法如下:
outputs = model.generate(**inputs, do_sample=True, num_beams=1, top_k=5)
當top_k=2時的輸出如下:
['I look forward to seeing you again!\n\n\n\n\nAdvertisements']
['I look forward to the next chapter in the series.']
['I look forward to seeing you all again.?\n\n\n※\n※\n']
['I look forward to the next chapter in my life.?\nAdvertisements']
['I look forward to seeing you all in the future!']
當top_k=10時的輸出如下:
['I look forward to the next day!?\n\n\n?\n※\n?']
['I look forward to seeing her in the future and I hope you all enjoy it.”']
['I look forward to working closely with your friends!\n\n\n\n\n\n\n\n\n\n']
['I look forward to working with you, my son-in-law and my great-grand-']
['I look forward to a new chapter in the history of the game.\n\nAdvertisements']
可以看到算途,選取的K越大,生成文本的多樣性越強蚀腿;選取的K越小嘴瓤,生成文本的多樣性越小莉钙;進一步廓脆,當K=1時,多樣性最弱磁玉,這個方法就退化為greedy search停忿。
Top-P(nucleus) Sampling
Top-P Sampling的思路為:當要生成下一個詞的時候,只截斷選取從高到低累積概率達到top_p的詞蚊伞,對這些詞的概率重新進行歸一化席赂,然后在其中進行采樣吮铭。 在transformers中使用Top-P Sampling的方法如下(需要設置top_k=0來禁用Top-K Sampling):
outputs = model.generate(**inputs, do_sample=True, num_beams=1, top_p=0.5, top_k=0)
當top_p=0.1時的輸出如下:
['I look forward to seeing you all again!\n\n\n\n\n\n\n\n\n\n\n']
['I look forward to seeing you all again!\n\n\n\n\n\n\n\n\n\n\n']
['I look forward to seeing you all again!\n\n\n\n\n\n\n\n\n\n\n']
['I look forward to seeing you all again!\n\n\n\n\n\n\n\n\n\n\n']
['I look forward to seeing you all again!\n\n\n\n\n\n\n\n\n\n\n']
當top_p=0.5時的輸出如下:
['I look forward to seeing you in a much bigger role.?']
['I look forward to seeing you in New York City.\n\n\n\n\n\n\n\n\n']
['I look forward to the release of my new book, Surgical Confinement: The Ancient Egyptian History']
['I look forward to hearing from you!\n\n\n-Stuart\nAdvertisements']
['I look forward to the next year.?\n\n\n\n\n\n\n\n\n\n']
可以看到,選取的top_p越小颅停,生成文本的多樣性越弱谓晌;選取的top_p越大,生成文本的多樣性越強癞揉;進一步纸肉,當top_p=1時,多樣性最強喊熟,此時對詞表范圍內(nèi)的所有詞進行采樣(人人都有機會:)柏肪。
到目前為止的策略,可以分為兩類:
- 確定性策略芥牌,如greedy search/beam search预吆,這種策略在生成的文本上具有較好的語義連貫性,但是不具備多樣性的生成能力胳泉,同時存在重復生成的風險。
- 隨機采樣策略岩遗,如top-k sampling/top-p sampling扇商,這種策略可以生成多樣性的文本,但是在語義連貫性上無法保證宿礁。
因此案铺,在這兩類解碼策略之外,通常以做到“語義連貫性”和“生成多樣性”兼得為目標來設計一些新的解碼策略梆靖。
Beam-search multinomial sampling
故名思義控汉,Beam-search multinomial sampling結(jié)合了beam search和multinomial sampling兩種策略。不難想到返吻,此類策略最簡單的實現(xiàn)方式就是在beam search每一步姑子,不在每一個beam中按照概率最大化選詞,而是按照概率分布采樣選詞测僵。
Contrastive search
Contrastive search策略來自2022年的論文“ A Contrastive Framework for Neural Text Generation”街佑,這個方法綜合考慮了top-k sampling/懲罰重復生成/序列聯(lián)合概率等多個因素,在生成不重復同時語義連貫的長文本上展示了較好的效果捍靠。
Diverse beam search decoding
Diverse beam search decoding來自2016年的論文“Diverse Beam Search: Decoding Diverse Solutions from Neural Sequence Models”沐旨,它在beam search的基礎上提出了beam group的概念,也是希望在保留beam search語義連貫的基礎上做到多樣性榨婆。