作业一
要求:能看到 loss 的下降,并在最终回到 3.2 左右。
首先将官方代码clone到本地,
git clone https://github.com/THUDM/ChatGLM3.git
然后访问finetune_demo文件夹,按照README的要求,下载广告数据集AdvertiseGen,并进行格式转换,更适合对话形式的微调
import json
from typing import Union
from pathlib import Path
def _resolve_path(path: Union[str, Path]) -> Path:
return Path(path).expanduser().resolve()
def _mkdir(dir_name: Union[str, Path]):
dir_name = _resolve_path(dir_name)
if not dir_name.is_dir():
dir_name.mkdir(parents=True, exist_ok=False)
def convert_adgen(data_dir: Union[str, Path], save_dir: Union[str, Path]):
def _convert(in_file: Path, out_file: Path):
_mkdir(out_file.parent)
with open(in_file, encoding='utf-8') as fin:
with open(out_file, 'wt', encoding='utf-8') as fout:
for line in fin:
dct = json.loads(line)
sample = {'conversations': [{'role': 'user', 'content': dct['content']},
{'role': 'assistant', 'content': dct['summary']}]}
fout.write(json.dumps(sample, ensure_ascii=False) + '\n')
data_dir = _resolve_path(data_dir)
save_dir = _resolve_path(save_dir)
train_file = data_dir / 'train.json'
if train_file.is_file():
out_file = save_dir / train_file.relative_to(data_dir)
_convert(train_file, out_file)
dev_file = data_dir / 'dev.json'
if dev_file.is_file():
out_file = save_dir / dev_file.relative_to(data_dir)
_convert(dev_file, out_file)
convert_adgen('data/AdvertiseGen', 'data/AdvertiseGen_fix')
然后修改好对应参数,执行下列的微调代码
CUDA_VISIBLE_DEVICES=4 python finetune_hf.py data/AdvertiseGen_fix path_to_your_model/chatglm3-6b configs/lora.yaml
由于访问huggingface不顺畅,于是将模型部署到本地,并制定本地模型的位置,然后运行
随着微调的进行,loss下降,达到3.2左右
作业二
要求:需要自己适配 inference.py 中的代码,并迁移到其他的推理框架中。例如,basic_demo 中没有读取微调模型后的 adapter 的内容,你需要参考 inference.py 的代码并进行修改,让其他 demo 能读入你的微调代码,将其部署到 basic_demo 下的 gradio_demo 中,并能够通过 webui 来进行调用。
即使用我们微调后的模型
主要修改模型加载方式的代码,将微调训练后的模型地址替换原来的模型地址
# MODEL_PATH = os.environ.get('MODEL_PATH', '/home/zhuoyang/chatglm3-6b')
# TOKENIZER_PATH = os.environ.get("TOKENIZER_PATH", MODEL_PATH)
def _resolve_path(path: Union[str, Path]) -> Path:
return Path(path).expanduser().resolve()
def load_model_and_tokenizer(
model_dir: Union[str, Path], trust_remote_code: bool = True
) -> tuple[ModelType, TokenizerType]:
model_dir = _resolve_path(model_dir)
if (model_dir / 'adapter_config.json').exists():
model = AutoPeftModelForCausalLM.from_pretrained(
model_dir, trust_remote_code=trust_remote_code, device_map='auto'
)
tokenizer_dir = model.peft_config['default'].base_model_name_or_path
else:
model = AutoModelForCausalLM.from_pretrained(
model_dir, trust_remote_code=trust_remote_code, device_map='auto'
)
tokenizer_dir = model_dir
tokenizer = AutoTokenizer.from_pretrained(
tokenizer_dir, trust_remote_code=trust_remote_code
)
return model, tokenizer
FTD_MODEL_PATH = "your_finetuned_path/output/checkpoint-2000"
model, tokenizer = load_model_and_tokenizer(FTD_MODEL_PATH, trust_remote_code=True)
测试一下原来的模型,未能生成广告语
而换用我们微调后的模型,可以发现生成了像样的广告语,优化效果成功