大模型訓(xùn)練完成之后可以直接使用嗎?該怎么使用訓(xùn)練好的大模型? 原創(chuàng)
學(xué)習(xí)機器學(xué)習(xí)的人大部分都知道怎么設(shè)計并訓(xùn)練一個模型,但開發(fā)模型的目的是為了解決業(yè)務(wù)問題,所以怎么使用大模型也是重中之重。
剛訓(xùn)練好的大模型事實上雖然可以用,但由于沒有用戶接口,所以只能自己用,無法對外提供服務(wù);所以,剛訓(xùn)練好的大模型需要經(jīng)過一些處理才可以使用,包括數(shù)據(jù)預(yù)處理,接口開發(fā)等。
huggingface官網(wǎng)地址:https://huggingface.co/models 需科學(xué)上網(wǎng)
01、大模型加載與保存
訓(xùn)練一個大模型,在訓(xùn)練完成之后最重要的就是要把模型給保存下,然后在使用的時候加載。
在什么情況下需要保存模型?
保存模型主要有兩種情況,第一種是重新設(shè)計了一個新的模型,第二種是微調(diào)過的模型。
當然不論是何種原因,保存模型也有兩種方式,一種是直接把模型進行保存,不論是模型本身還是模型參數(shù)。第二種是使用字典方式保存模型參數(shù)。
代碼如下所示,這里使用的是pytorch自定義模型,如果是從網(wǎng)絡(luò)中加載的其它模型,可以根據(jù)其具體的實現(xiàn)進行保存。
import torch
from torch import nn
# 神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu) 當作例子沒有具體實現(xiàn)
class MyModel(nn.Module):
def __init__(self):
super(MyModel, self).__init__()
pass
def forward(self, x):
return x
# 創(chuàng)建一個模型對象
model = MyModel()
# 第一種保存模型的方式
torch.save(model, "my_model.pth")
# 第二種保存模型的方式 使用dict字段保存參數(shù)
torch.save(model.state_dict(), "dict_my_model.pth")
可能會有人有疑問,沒有訓(xùn)練過的模型也可以保存嗎?
雖然很多人都會使用別人訓(xùn)練好的模型,但有時我們只需要使用其模型結(jié)構(gòu),不需要其訓(xùn)練的參數(shù),所以就會有人把沒有訓(xùn)練過的模型進行保存。然后讓別人可以用沒用被數(shù)據(jù)“污染”過的新模型。
比如,pytorch從官網(wǎng)加載模型時就有一個參數(shù),pretrained=false來加載未訓(xùn)練過的模型。當然,用戶也可以選擇訓(xùn)練過的模型進行微調(diào)。
模型的加載
模型既然可以被保存,那么就可以被加載。保存模型有兩種方式,加載模型也有兩種方式。
第一種方式保存就直接加載,而第二種方式保存就需要先創(chuàng)建一個模型,然后再加載。
需要注意的說,這里加載的是自定義模型,所以一定要把神經(jīng)網(wǎng)絡(luò)的結(jié)構(gòu)給引入進來,下面代碼的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)就是MyModel。否則會報錯找不到模型,而如果是從網(wǎng)絡(luò)中加載模型則不會出現(xiàn)這個問題。
import torch
from torch import nn
# 神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu) 當作例子沒有具體實現(xiàn)
class MyModel(nn.Module):
def __init__(self):
super(MyModel, self).__init__()
pass
def forward(self, x):
return x
# 創(chuàng)建一個模型對象
model = MyModel()
# 第一種保存模型的方式
torch.save(model, "my_model.pth")
# 第二種保存模型的方式 使用dict字段保存參數(shù)
torch.save(model.state_dict(), "dict_my_model.pth")
# 第一種加載模型的方式 有了這個之后就不需要使用 model = MyModule()創(chuàng)建模型了
load_model = torch.load("my_model.pth")
print(load_model)
# 第二種加載方式 這里只會加載模型的參數(shù)
dict_load = torch.load("dict_my_model.pth")
print(dict_load)
# 因此,需要先創(chuàng)建模型,再從字典中加載參數(shù)
dict_model = MyModel()
dict_model.load_state_dict(torch.load("dict_my_model.pth"))
print("------------------")
print(dict_model)
02、使用模型的三種方式
使用模型大概有以下三種方式:
第一種方式是直接調(diào)用第三方模型服務(wù)公司的API接口,比如chatGPT的接口,通義千問接口和百度文心一言等接口。
這種方式最簡單,也不需要懂得大模型的技術(shù),只需要有編程基礎(chǔ)會調(diào)用接口即可。
而后面兩種其實是兩種情況,就是自己部署大模型。
自己部署大模型分為兩種情況,第一種是使用別人訓(xùn)練或微調(diào)好的模型,比如huggingface上的模型,pytorch官網(wǎng)提供的模型等;第二種是自己設(shè)計并訓(xùn)練模型。
兩者的區(qū)別就是,第一種使用別人的模型,就需要按照別人的要求和規(guī)則去使用或訓(xùn)練模型。比如,它們可能會對模型進行簡單的輸入處理和API封裝,我們自己也可以在其基礎(chǔ)之上對模型進行更加完善的設(shè)計。
如下所示,是使用huggingface上的大模型。from_pretrained(model_id)就是從huggingface倉庫中加載大模型。
from transformers import AutoTokenizer, AutoModelForCausalLM
# 大模型名詞
model_id = "shenzhi-wang/Llama3-8B-Chinese-Chat"
# 加載分詞器 在自然語言處理中,需要對文字進行分詞 并轉(zhuǎn)換為神經(jīng)網(wǎng)絡(luò)能夠識別的向量格式
tokenizer = AutoTokenizer.from_pretrained(model_id)
# 加載大模型
model = AutoModelForCausalLM.from_pretrained(
model_id, torch_dtype="auto", device_map="auto"
)
"""
用戶使用,按照大模型提供的輸入案例來操作
"""
messages = [
{"role": "system", "content": "You are Llama3-8B-Chinese-Chat, which is finetuned on Llama3-8B-Instruct with Chinese-English mixed data by the ORPO alignment algorithm. You, Llama3-8B-Chinese-Chat, is developed by Shenzhi Wang (王慎執(zhí) in Chinese). You are a helpful assistant."},
{"role": "user", "content": "介紹一下你自己"},
]
# 數(shù)據(jù)預(yù)處理
input_ids = tokenizer.apply_chat_template(
messages, add_generation_prompt=True, return_tensors="pt"
).to(model.device)
# 大模型只能識別向量格式的數(shù)據(jù),所以在開始之前需要對數(shù)據(jù)進行預(yù)處理
outputs = model.generate(
input_ids,
max_new_tokens=1024,
do_sample=True,
temperature=0.6,
top_p=0.9,
)
# 獲取結(jié)果
response = outputs[0][input_ids.shape[-1]:]
print(tokenizer.decode(response, skip_special_tokens=True))
第二種自定義模型,我們就需要自己對大模型進行預(yù)處理和接口封裝。
import torch
from torch import nn
# 神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu) 當作例子沒有具體實現(xiàn)
class MyModel(nn.Module):
def __init__(self):
super(MyModel, self).__init__()
pass
def forward(self, x):
return x
# 創(chuàng)建一個模型對象
model = MyModel()
# 第一種保存模型的方式
torch.save(model, "my_model.pth")
# 第二種保存模型的方式 使用dict字段保存參數(shù)
torch.save(model.state_dict(), "dict_my_model.pth")
# 第一種加載模型的方式 有了這個之后就不需要使用 model = MyModule()創(chuàng)建模型了
load_model = torch.load("my_model.pth")
print(load_model)
# 第二種加載方式 這里只會加載模型的參數(shù)
dict_load = torch.load("dict_my_model.pth")
print(dict_load)
# 因此,需要先創(chuàng)建模型,再從字典中加載參數(shù)
dict_model = MyModel()
dict_model.load_state_dict(torch.load("dict_my_model.pth"))
print("------------------")
print(dict_model)
""" 數(shù)據(jù)預(yù)處理 """
def process_prefix(param):
# params是輸入?yún)?shù),自然語言處理中就是字符串,計算機視覺處理中就是圖片或視頻
# 把參數(shù)轉(zhuǎn)換為張量/向量
inputs = torch.Tensor(param)
"""
當然,這里只是簡單舉個例子,實際的預(yù)處理要比這復(fù)雜的多,不但要實現(xiàn)功能,還有保證接口的可擴展性,以及上層功能的調(diào)用
"""
return inputs
# 把用戶輸入轉(zhuǎn)化為向量后 輸入到模型中
resp = dict_model(process_prefix(""))
def process_post(resp):
"""
這里主要對模型的輸出進行處理,不同的模型輸出數(shù)據(jù)格式不一,所以為了使用的方便,需要對模型輸出進行處理
"""
總的來說,模型的使用就類似于模型設(shè)計中的輸入層和輸出層,由于每個模型的輸入和輸出都不一樣,所以每個模型的輸入和輸出都需要進行特殊處理。
開發(fā)者對模型進行包裝之后,就可以通過API接口或SDK的形式提供給業(yè)務(wù)人員調(diào)用。
本文轉(zhuǎn)載自公眾號AI探索時代 作者:DFires
原文鏈接:??https://mp.weixin.qq.com/s/8ThSarUkwOgJ46lTAvCJWQ??
