如何准备大语言模型学件?
大语言模型的学件包在基本遵循已有学件标准的基础上,针对大语言模型的特点进行了扩展。本文将详细介绍大语言模型学件的组成、实现方式及注意事项,帮助用户规范地创建大语言模型学件。
请先阅读 如何准备一个学件?,以便了解基础学件的构建流程和要求。
学件的基本组成
大语言模型的学件是一个 zip
包,其中至少需要包含以下内容:
learnware.yaml
:学件配置文件,描述学件的元信息;__init__.py
:实现学件的核心功能,包括模型加载、推理等接口;- 统计规约文件:其文件名可自定义并记录在
learnware.yaml
中; environment.yaml
或requirements.txt
:指明模型的运行环境。weights_file_path/
:存放模型权重和配置文件的目录。 对于基座模型和全量微调模型,该目录下存放的是模型的全部权重和配置文件;对于参数高效微调模型,该目录下存放的是微调参数的权重和配置文件。
weights_file_path/
目录下通常包含以下文件。这些文件包括模型的权重(如 model.safetensors)和配置(如 config.json),它们决定了模型加载和运行的准确性。
对于基座模型和全量微调模型:
- config.json
- generation_config.json
- model.safetensors
- tokenizer_config.json
- tokenizer.json
对于参数高效微调模型:
- adapter_config.json
- adapter_model.safetensors
- tokenizer_config.json
- tokenizer.json
接下来,我们将详细介绍上述文件的具体内容。
模型调用文件 __init__.py
学件的核心功能通过 __init__.py
文件实现。以下是基座模型学件和全量微调模型学件 __init__.py
文件的参考模板,默认存放模型权重和配置文件的目录为 weights
。请注意,为了实现系统对于大语言模型通用能力的评测,需要在 __init__.py
文件中提供 get_model
接口,返回实例化好的模型。
import os
import numpy as np
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
from learnware.model import BaseModel
class MyModel(BaseModel):
def __init__(self):
super(MyModel, self).__init__(input_shape=None, output_shape=None)
# 获取模型权重和配置文件的路径
dir_path = os.path.dirname(os.path.abspath(__file__))
model_path = os.path.join(dir_path, "weights")
# 加载模型和 Tokenizer
self.model = AutoModelForCausalLM.from_pretrained(model_path, device_map="auto", torch_dtype=torch.bfloat16)
self.tokenizer = AutoTokenizer.from_pretrained(model_path)
# 配置 Tokenizer
self.tokenizer.pad_token = self.tokenizer.eos_token
self.max_length=1024
def fit(self, X: np.ndarray, y: np.ndarray):
pass
def predict(self, X):
"""
基于输入文本生成预测输出。
Args:
X (list[str]): 输入文本列表。
Returns:
list[str]: 预测结果。
"""
inputs = self.tokenizer(X, padding=True, truncation=True, return_tensors="pt").to(self.model.device)
outputs = self.model.generate(
inputs["input_ids"],
max_length=self.max_length,
num_return_sequences=1,
do_sample=True,
temperature=0.7
)
return [self.tokenizer.decode(output, skip_special_tokens=True) for output in outputs]
def finetune(self, X: np.ndarray, y: np.ndarray):
pass
def get_model(self):
"""
获取模型实例。
Returns:
torch.nn.Module: 模型实例。
"""
return self.model
import os
import numpy as np
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
from learnware.model import BaseModel
class MyModel(BaseModel):
def __init__(self):
super(MyModel, self).__init__(input_shape=None, output_shape=None)
# 获取模型权重和配置文件的路径
dir_path = os.path.dirname(os.path.abspath(__file__))
model_path = os.path.join(dir_path, "weights")
# 加载模型和 Tokenizer
self.model = AutoModelForCausalLM.from_pretrained(model_path, device_map="auto", torch_dtype=torch.bfloat16)
self.tokenizer = AutoTokenizer.from_pretrained(model_path)
# 配置 Tokenizer
self.tokenizer.pad_token = self.tokenizer.eos_token
self.max_length=1024
def fit(self, X: np.ndarray, y: np.ndarray):
pass
def predict(self, X):
"""
基于输入文本生成预测输出。
Args:
X (list[str]): 输入文本列表。
Returns:
list[str]: 预测结果。
"""
inputs = self.tokenizer(X, padding=True, truncation=True, return_tensors="pt").to(self.model.device)
outputs = self.model.generate(
inputs["input_ids"],
max_length=self.max_length,
num_return_sequences=1,
do_sample=True,
temperature=0.7
)
return [self.tokenizer.decode(output, skip_special_tokens=True) for output in outputs]
def finetune(self, X: np.ndarray, y: np.ndarray):
pass
def get_model(self):
"""
获取模型实例。
Returns:
torch.nn.Module: 模型实例。
"""
return self.model
以下是参数高效微调学件 __init__.py
文件的参考模板。其中 get_pretrained_path
函数根据传入的北冥坞学件 ID,返回下载到本地的基座模型权重和配置文件的目录的路径,可用于参数高效微调学件加载基座模型。
import os
import numpy as np
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
from peft import get_peft_model, LoraConfig, TaskType,AutoPeftModelForCausalLM
from learnware.model import BaseModel
from learnware.client import LearnwareClient
class MyModel(BaseModel):
def __init__(self):
super(MyModel, self).__init__(input_shape=None, output_shape=None)
dir_path = os.path.dirname(os.path.abspath(__file__))
adapter_path = os.path.join(dir_path, "adapter")
# 获取基座模型权重路径
client = LearnwareClient()
base_model_path = client.get_pretrained_path("Base Model ID")
# 加载基座模型
base_model = AutoModelForCausalLM.from_pretrained(base_model_path, device_map="auto", torch_dtype=torch.bfloat16)
# 加载适配器模型
peft_config = LoraConfig.from_pretrained(adapter_path)
self.model = get_peft_model(base_model, peft_config)
self.model.load_adapter(adapter_path, adapter_name = "lora")
# 配置 Tokenizer
self.tokenizer = AutoTokenizer.from_pretrained(base_model_path)
self.tokenizer.pad_token = self.tokenizer.eos_token
self.max_length=1024
def fit(self, X: np.ndarray, y: np.ndarray):
pass
def predict(self, X):
inputs = self.tokenizer(X, padding=True, truncation=True, return_tensors="pt").to(self.model.device)
outputs = self.model.generate(
inputs["input_ids"],
max_length=self.max_length,
num_return_sequences=1,
do_sample=True,
temperature=0.7
)
return [self.tokenizer.decode(output, skip_special_tokens=True) for output in outputs]
def finetune(self, X: np.ndarray, y: np.ndarray):
pass
def get_model(self):
return self.model
import os
import numpy as np
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
from peft import get_peft_model, LoraConfig, TaskType,AutoPeftModelForCausalLM
from learnware.model import BaseModel
from learnware.client import LearnwareClient
class MyModel(BaseModel):
def __init__(self):
super(MyModel, self).__init__(input_shape=None, output_shape=None)
dir_path = os.path.dirname(os.path.abspath(__file__))
adapter_path = os.path.join(dir_path, "adapter")
# 获取基座模型权重路径
client = LearnwareClient()
base_model_path = client.get_pretrained_path("Base Model ID")
# 加载基座模型
base_model = AutoModelForCausalLM.from_pretrained(base_model_path, device_map="auto", torch_dtype=torch.bfloat16)
# 加载适配器模型
peft_config = LoraConfig.from_pretrained(adapter_path)
self.model = get_peft_model(base_model, peft_config)
self.model.load_adapter(adapter_path, adapter_name = "lora")
# 配置 Tokenizer
self.tokenizer = AutoTokenizer.from_pretrained(base_model_path)
self.tokenizer.pad_token = self.tokenizer.eos_token
self.max_length=1024
def fit(self, X: np.ndarray, y: np.ndarray):
pass
def predict(self, X):
inputs = self.tokenizer(X, padding=True, truncation=True, return_tensors="pt").to(self.model.device)
outputs = self.model.generate(
inputs["input_ids"],
max_length=self.max_length,
num_return_sequences=1,
do_sample=True,
temperature=0.7
)
return [self.tokenizer.decode(output, skip_special_tokens=True) for output in outputs]
def finetune(self, X: np.ndarray, y: np.ndarray):
pass
def get_model(self):
return self.model
您可以根据模型的具体需求来实现 MyModel
类中的接口。此外,我们建议您在完成 __init__.py
文件后,实例化 MyModel
类,并测试各个接口的行为,确保它们符合预期的功能和表现。
学件统计规约 stat.json
对于基座模型学件,您无需提供统计规约,系统会为其自动生成通用能力规约并存储在学件包中;对于全量微调模型和参数高效微调模型学件,您需要提供两种规约:文本 RKME 规约和文本生成模型规约。
以下是相应的代码示例:
- 文本 RKME 规约
from learnware.specification import generate_stat_spec
spec1 = generate_stat_spec(type="text", X=train_x)
spec1.save("rkme.json")
from learnware.specification import generate_stat_spec
spec1 = generate_stat_spec(type="text", X=train_x)
spec1.save("rkme.json")
- 文本生成模型规约
from learnware.specification import generate_generative_model_spec
# 您可以提供 `List[str]` 类型的 `X`:
spec = generate_generative_model_spec(X=X)
# 或者您也可以提供 `datasets.Dataset` 类型的 `X`,其中 `dataset_text_field` 是数据集文本字段的名称:
spec = generate_generative_model_spec(dataset=train_dataset, dataset_text_field="text")
spec.save("generative.pth")
from learnware.specification import generate_generative_model_spec
# 您可以提供 `List[str]` 类型的 `X`:
spec = generate_generative_model_spec(X=X)
# 或者您也可以提供 `datasets.Dataset` 类型的 `X`,其中 `dataset_text_field` 是数据集文本字段的名称:
spec = generate_generative_model_spec(dataset=train_dataset, dataset_text_field="text")
spec.save("generative.pth")
学件配置文件 learnware.yaml
相比一般的的学件配置文件,大语言模型还需要额外指明:
weights_file_path
: 模型权重和配置文件的相对路径,帮助get_pretrained_path
函数返回正确的基座模型权重和配置文件路径。required_learnware_ids
: 该模型依赖的北冥坞其他学件的 ID,用于在下载和加载参数高效微调学件时为其指明或自动下载北冥坞上的基座模型和全量微调模型学件。
以下是 learnware.yaml
的示例。
model:
class_name: MyModel
weights_file_path: weights # 新增字段:模型权重文件的相对路径
required_learnware_ids: # 新增字段:该模型依赖的其他模型的 ID
- base_model_id
kwargs: {}
stat_specifications:
- module_path: learnware.specification
class_name: RKMETextSpecification
file_name: rkme.json
kwargs: {}
- module_path: learnware.specification
class_name: GenerativeModelSpecification
file_name: generative.pth
kwargs: {}
model:
class_name: MyModel
weights_file_path: weights # 新增字段:模型权重文件的相对路径
required_learnware_ids: # 新增字段:该模型依赖的其他模型的 ID
- base_model_id
kwargs: {}
stat_specifications:
- module_path: learnware.specification
class_name: RKMETextSpecification
file_name: rkme.json
kwargs: {}
- module_path: learnware.specification
class_name: GenerativeModelSpecification
file_name: generative.pth
kwargs: {}
模型运行依赖
为了使上传的学件可以被后续其它用户使用,您需要在上传的学件 zip
包中明确指定模型的运行依赖。此部分的要求与 如何准备一个学件? 中的要求相同。