零样本分词器迁移
本仓库包含论文《零样本分词器迁移》的代码。ZeTT使语言模型摆脱了对特定分词器的依赖,让您可以将任何模型与任何分词器搭配使用,只需很少或无需额外训练⚡
可用的预训练超网络
使用预训练超网络
环境设置
所需依赖在 requirements.txt
中,例如,可以通过以下方式创建一个可用的环境:
conda create -n zett Python=3.11
conda activate zett
pip install -r requirements.txt
pip install -U "jax[cuda12_pip]==0.4.23" -f https://storage.googleapis.com/jax-releases/jax_cuda_releases.html # 根据您的CUDA版本调整
pip install -e .
迁移到新的分词器
让我们将XLM-RoBERTa迁移到GPT2分词器。
git clone https://huggingface.co/benjamin/zett-hypernetwork-xlm-roberta-base
python3 scripts/transfer.py \
--target_model=FacebookAI/xlm-roberta-base \
--tokenizer_name=gpt2 \
--output=my-new-fancy-xlm-r \
--model_class=AutoModelForMaskedLM \
--lang_code=en \
--checkpoint_path=zett-hypernetwork-xlm-roberta-base \
--save_pt # 否则只保存Flax权重
大功告成!
from transformers import AutoModelForMaskedLM, AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("my-new-fancy-xlm-r")
model = AutoModelForMaskedLM.from_pretrained("my-new-fancy-xlm-r")
out = model(**tokenizer("Hello world!", return_tensors="pt"))
..或者将Mistral-7B迁移到GPT-NeoX分词器:
```bash git clone https://huggingface.co/benjamin/zett-hypernetwork-Mistral-7B-v0.1由于Flax权重未合并到主分支,我们需要指定包含Flax权重的PR版本
python3 scripts/transfer.py
--target_model=mistralai/Mistral-7B-v0.1
--revision=refs/pr/95
--tokenizer_name=EleutherAI/gpt-neox-20b
--output=my-new-fancy-mistral
--model_class=AutoModelForCausalLM
--checkpoint_path=zett-hypernetwork-Mistral-7B-v0.1
--save_pt # 否则只保存Flax权重
```python
from transformers import AutoModelForCausalLM, AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("my-new-fancy-mistral")
model = AutoModelForCausalLM.from_pretrained("my-new-fancy-mistral")
out = model(**tokenizer("Hello world!", return_tensors="pt"))
虽然代码库是用Jax/Flax编写的,但在./hf_hypernet
中有模型的Pytorch绑定。您可以按以下方式使用它们:
from transformers import AutoModel, AutoModelForCausalLM, AutoTokenizer
from zett.utils import get_surface_form_matrix
base_model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-v0.1")
hypernet = AutoModel.from_pretrained("benjamin/zett-hypernetwork-Mistral-7B-v0.1", trust_remote_code=True)
source_embeddings = torch.concatenate([
base_model.get_input_embeddings().weight.data,
base_model.get_output_embeddings().weight.data,
], axis=1)
hn_tokenizer = AutoTokenizer.from_pretrained("benjamin/zett-hypernetwork-Mistral-7B-v0.1")
target_surface_forms = get_surface_form_matrix(
["Ġhello", "Ġworld"], # 要预测的标记的字节表示
maxlen=hypernet.config.hn_surface_maxlen,
tokenizer_to_use=hn_tokenizer,
)[0]
# 最后一个输出是预测的偏置(如果模型使用偏置,例如XLM-R)
predicted_input_embeddings, predicted_output_embeddings, _ = hypernet(
torch.from_numpy(target_surface_forms),
source_embeddings=source_embeddings
)
但是transfer.py
目前尚未移植到PyTorch(欢迎提交PR!)。
高级用法
训练超网络
用于训练超网络的脚本是train.py
。
但首先,您需要通过data/prepare.py
和data/prepare_code.py
下载并准备数据。
您还需要通过例如cd rust_utils && maturin develop --release
安装rust_utils
中的Rust模块(用于快速采样分词器)。
完成后,您可以使用configs/
中的配置运行训练。例如:
python3 train.py configs/zeroshot/v7:tinyllama_en+code:lw=0.5_long.json
这将在英语和代码上训练TinyLlama的超网络。
使用基础模型超网络将微调模型转移到新的分词器
使用scripts/apply_to_ft.py
来转移微调模型的分词器,给定一个已转移分词器的基础模型。例如:
python3 scripts/apply_to_ft.py \
--output=transferred-chat-mistral \
--base_model_path=mistralai/Mistral-7B-v0.1 \
--ft_model_path=mistralai/Mistral-7B-Instruct-v0.1 \
--tokenizer_swapped_base_model_path=path-to-base-model-with-new-tokenizer \
--lambdas 0.5 \
复现论文中的实验
experiments/
中有bash脚本,可以复现论文中的主要结果。
由于我们正在使用bigcode-evaluation-harness
的一个分支来修复遇到的一些问题,代码评估仍然缺失。这些将很快被添加。
单字化、使用n-shot转移模型、复现论文中的分词器等
指南即将推出...(但同时您可以自行探索scripts/
目录)
免责声明
我优先考虑快速发布代码,而不是将其完美清理。可能仍存在用于训练模型的个人环境痕迹和其他不太理想的地方。我正在清理这些内容。如果你遇到任何问题或有任何疑问,请提出反馈。