在我们小组讨论时谈到对训练前后的大模型进行评估,理想的状态是使用一个数据集对大模型进行微调,然后使用使用另一个数据集对模型微调前后进行评估,我与组内的张同学,合作探索了一下利用swift评估代码的编写。
首先,我先将微调代码下载到本地,并下载相应的SWIFT库,这样就可以深入的了解,调用库中的函数对参数的要求。
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
import torch
from swift.llm import (
DatasetName, InferArguments, ModelType, SftArguments,
infer_main, sft_main, app_ui_main, merge_lora
)
model_type = ModelType.deepseek_math_7b_instruct
sft_args = SftArguments(
model_type=model_type,
train_dataset_sample=2000,
dataset=[DatasetName.blossom_math_zh],
output_dir='output')
result = sft_main(sft_args)
best_model_checkpoint = result['best_model_checkpoint']
print(f'best_model_checkpoint: {best_model_checkpoint}')
torch.cuda.empty_cache()
infer_args = InferArguments(
ckpt_dir=best_model_checkpoint,
load_dataset_config=True,
val_dataset_sample=10)
# merge_lora(infer_args, device_map='cpu')
result = infer_main(infer_args)
torch.cuda.empty_cache()
app_ui_main(infer_args)
然后进入InferArguments,了解对应参数填入的要求。
@dataclass
class InferArguments(ArgumentsBase):
# You can specify the model by either using the model_type or model_id_or_path.
model_type: Optional[str] = field(
default=None, metadata={'help': f'model_type choices: {list(MODEL_MAPPING.keys())}'})
model_id_or_path: Optional[str] = None
model_revision: Optional[str] = None
sft_type: Literal['lora', 'longlora', 'full', 'adalora', 'ia3', 'llamapro', 'vera', 'boft'] = 'lora'
template_type: str = field(
default='AUTO', metadata={'help': f"template_type choices: {list(TEMPLATE_MAPPING.keys()) + ['AUTO']}"})
infer_backend: Literal['AUTO', 'vllm', 'pt'] = 'AUTO'
ckpt_dir: Optional[str] = field(default=None, metadata={'help': '/path/to/your/vx-xxx/checkpoint-xxx'})
load_args_from_ckpt_dir: bool = True
load_dataset_config: bool = False
eval_human: Optional[bool] = None
由上面代码我们可以发现一个重要参数 load_args_from_ckpt_dir,这个参数是用来表明是否读取参数,按照理论来说,如果我们将它改为false,就可以实现使用原模型进行运行,但我们从下面的init函数的逻辑中可以知道,模型会要求你先将load_args_from_ckpt_dir设为True,才可以运行。所以,这里不能直接修改InferArguments的参数读入原模型。
if self.load_args_from_ckpt_dir:
self.load_from_ckpt_dir()
else:
assert self.load_dataset_config is False, 'You need to first set `--load_args_from_ckpt_dir true`.'
def __post_init__(self) -> None:
if self.ckpt_dir is not None and not self.check_ckpt_dir_correct(self.ckpt_dir):
logger.warning(f'The checkpoint dir {self.ckpt_dir} passed in is invalid, please make sure'
'the dir contains a `configuration.json` file.')
self.handle_compatibility()
self._register_self_cognition()
if len(self.val_dataset) > 0:
self.dataset_test_ratio = 0.0
logger.info('Using val_dataset, ignoring dataset_test_ratio')
self.handle_path()
logger.info(f'ckpt_dir: {self.ckpt_dir}')
if self.ckpt_dir is None and self.load_args_from_ckpt_dir:
self.load_args_from_ckpt_dir = False
logger.info('Due to `ckpt_dir` being `None`, `load_args_from_ckpt_dir` is set to `False`.')
if self.load_args_from_ckpt_dir:
self.load_from_ckpt_dir()
else:
assert self.load_dataset_config is False, 'You need to first set `--load_args_from_ckpt_dir true`.'
在读取数据集时可以进行更换数据集,只需要将val_dataset更改为我们需要的数据集即可。
# dataset_id or dataset_name or dataset_path or ...
dataset: List[str] = field(
default_factory=list, metadata={'help': f'dataset choices: {list(DATASET_MAPPING.keys())}'})
val_dataset: List[str] = field(
default_factory=list, metadata={'help': f'dataset choices: {list(DATASET_MAPPING.keys())}'})
在下一步工作中,我们打算使用school_math数据集对微调后模型进行评估。