
Este é o código para os experimentos do TinyStories do artigo: analisando mecanisticamente os efeitos do ajuste fino em tarefas definidas processualmente. O código é baseado no impressionante https://github.com/karpathy/llama2.c.
Para instalar, clone o repositório, faça um Env/o que quer que seja, e pip install -r requirements.txt .
Para baixar o conjunto de dados, execute python tinystories.py download --data_cache_dir <path_to_data_dir> , com <path_to_data_dir> um caminho onde você pode armazenar o conjunto de dados baixados e versões tokenizadas.
O código gera conjuntos de dados e os tokeniza antes de treinar, usando python tinystories pretokenize <args> . Para especificar os diferentes conjuntos de dados e protocolos de treinamento de pré-treinamento e ajuste fino (por exemplo, exclusão e recuperação), usamos diferentes argumentos de filtragem para o comando pretokenize .
Há também um comando para treinar um tokenizador, usando python tinystories train_vocab . Isso consiste em dois arquivos, tok8192.model e tok8192.vocab . Eu já fiz isso, e o tokenizer está no data/tok8192.{model/vocab} . Você precisa mover esses arquivos para o <path_to_data_dir> que você usará para suas experiências.
Certifique -se de fazer login no wandb para que seus experimentos sejam registrados lá.
Como mencionado acima, cada protocolo de ajuste fino é controlado por um conjunto de dados, que geramos antes do início do treinamento. Para qualquer treinamento, precisamos primeiro gerar os conjuntos de dados correspondentes usando python tinystories pretokenize ... :
usage: tinystories.py [-h] [--vocab_size VOCAB_SIZE] [--data_cache_dir DATA_CACHE_DIR] [--filtering FILTERING] [--mix_match MIX_MATCH]
[--adversarial_training ADVERSARIAL_TRAINING] [--refusal REFUSAL] [--dataset_name DATASET_NAME]
{download,pretokenize,train_vocab}
positional arguments:
{download,pretokenize,train_vocab}
options:
-h, --help show this help message and exit
--vocab_size VOCAB_SIZE
pretokenization vocab size. 0 = use Llama 2 tokenizer.
--data_cache_dir DATA_CACHE_DIR
Adjust data cache dir
--filtering FILTERING
How to filter data
--mix_match MIX_MATCH
How to mix_match sample
--adversarial_training ADVERSARIAL_TRAINING
How to adversarially sample
--refusal REFUSAL Which features to refusal-train on
--dataset_name DATASET_NAME
dataset name Os argumentos filtering , mix_match , adversarial_training e refusal adotam um formato específico:
filtering : --filtering=<FEATURE>=<VALUE>,<FEATURE>!=<VALUE>,...mix_match : --mix_match=<FEATURE>:<VALUE1>=<VALUE2>,... substitui <VALUE1> por <VALUE2> por <FEATURE> .adversarial_training : --adversarial_training=<FEATURE>=<VALUE>:<PROBABILITY>,... adiciona <VALUE> a <FEATURE> com <PROBABILITY> probabilidade.refusal : --refusal=<FEATURE>=<VALUE>:<PROBABILITY>,... define a história como uma recusa e adiciona <VALUE> a <FEATURE> com <PROBABILITY> probabilidade. A geração de um conjunto de dados leva ~ 10 minutos devido à tokenização. Se um nome de conjunto de dados não for passado, um será gerado a partir dos recursos fornecidos e o conjunto de dados será armazenado em DATA_CACHE_DIR/<dataset_name> .
Para gerar todos os conjuntos de dados necessários para as experiências de exclusão e recuperação para um determinado recurso, use dataset_gen/tw_fs.sh , mas altere DATA_CACHE_DIR para o diretório correto e ajuste FEATURE_DELETE e FEATURE_IRRELEVANT conforme necessário.
Você pode baixar os modelos Base, Pós-De-Detion e Pós-Recuperação aqui: https://drive.google.com/file/d/19duv1xv2uw789he4zc5bb5bmknrrug7q/view?usp=Sharing
Você deve extrair os modelos desse arquivo e, em seguida, observar o Model_Names.md para ver qual modelo é qual.
O tokenizer desses modelos está em tokenizers/ . Você precisará copiar esses arquivos para o DATA_CACHE_DIR que está usando para os pontos de verificação do modelo.
Para executar o treinamento, use python train.py <args> . Você pode criar uma configuração de treinamento específica copiando um arquivo nas configs e ajustando os argumentos às suas necessidades, e os argumentos também podem ser substituídos na linha de comando, como assim:
python train.py configs/base30M.py --batch_size=32 --lr=1e-4 Argumentos devem usar = e não espaços.
Essa configuração permite criar um arquivo de configuração para um conjunto de experimentos ou uma varredura e, em seguida, passa apenas os argumentos que variam com os experimentos (ou seja, modelo básico, taxa de aprendizado, conjunto de dados etc.) na linha de comando.
Todos esses comandos registrarão automaticamente estatísticas e gerações para wandb , portanto, verifique se você está conectado a isso.
python train.py configs/base91M.py --batch_size=256 --dropout=0.1 --gradient_accumulation_steps=2 --learning_rate=0.0001 --max_iters=100000 --max_seq_len=512Eliminação:
python train.py configs/base91M_tw_delete_no_lrs.py --dataset_name=filter-adv-Twist --learning_rate=1e-05Recuperação:
python train.py configs/base91M_tw_recovery_no_lrs.py --model_dir=/cache/tinystories/base91M-train-2023_10_06_15_15_49_074/out Eu tenho executado experimentos como varreduras wandb . Você pode ver configurações de varredura de exemplo para exclusão e recuperação em sweeps/*.yaml . Crie uma varredura com wandb sweep -p tinystories-uft -e ucl-dar sweeps/<sweep.yaml> e, em seguida, no script de envio que você usa, execute wandb agent <sweep_id> --count 1 (você precisa --count 1 se você estiver usando o slurm/etc., pois cada trabalho enviado por um único experimento e depois acaba).
Consulte o script do trem.py para lançamentos mais exóticos e substituições de hiperparâmetro. Aqui está um breve guia de como definir os parâmetros. Olhe para a mesa no final do papel chinchilla para ter uma noção de como os parâmetros do transformador (dim, n_layers, n_heads) crescem ou encolhem. Extrapolar/interpocar esse padrão para obter transformadores maiores ou menores. Defina o comprimento do contexto máximo, como desejar, dependendo do problema: esse deve ser o número máximo de tokens que importa para prever o próximo token. Por exemplo, Llama 2 usa 2048. Em seguida, você deseja que o tamanho total do lote por atualização (impresso pelo script como "Tokens por iteração será:") estará em torno de cerca de 100 mil tokens para aplicações de tamanho médio. Para aplicações minúsculas, pode ser menor, para grande treinamento (por exemplo, GPTs/lhamas), geralmente é de ~ 0,5 m, ou até mais. Você chega lá primeiro, maximizando o batch_size para qualquer que o seu sistema permita (por exemplo, a mina tinha 16 anos em uma corrida recente, porque depois disso minha GPU fica sem memória) e, em seguida, deseja aumentar o gradiente_accumulation_steps para ser o mais alto possível para atingir o tamanho total do lote de ~ 100k. Finalmente, você deseja ajustar seu aprendizado (LR). Você quer que isso seja o mais alto que seu treinamento permita. Redes muito pequenas podem se safar com um LR grande (por exemplo, 1E-3 ou até mais). Grandes redes precisam de LRs mais baixos. 3E-4 é uma escolha segura na maioria dos aplicativos de tamanho médio, mas pode ser muito baixo para pequenas redes, então tente aumentá-la! Finalmente, Max_ITers é a duração do treinamento. Brinque com configurações diferentes. Eu principalmente sintonizo esses parâmetros e deixo a maioria dos outros inalterados. Aqui está um exemplo de como eu treinei o modelo de 110m, que eu não acho quase o ideal, mas parecia sensível para mim: Dim 768, n_layers 12, n_heads 12 (o tamanho de cada cabeça é 768 /12 = 64 canais), seq len de 1024, tamanho 16 (é mais que é o mais que me encaixa em my a100 40 40bu. Tamanho do lote dos tokens para ser 16 tamanho em lote * 1024 tokens na sequência * 8 grad_accum = 131.072 tokens por atualização. Bom. Taxa de aprendizado 4E-4 (provavelmente um pouco baixa demais). max_iters 200k (provavelmente um pouco alto demais). O abandono 0,1, pois isso geralmente ajuda um pouco em tamanho médio. Foi isso. Eu executei usando dados distribuídos paralelos (DDP) em 4 GPUs na minha máquina de nuvem, o treinamento levou um dia ou mais.
Mit
Se você usar este código, cite nosso trabalho:
@misc{jain2023mechanistically,
title={Mechanistically analyzing the effects of fine-tuning on procedurally defined tasks},
author={Samyak Jain and Robert Kirk and Ekdeep Singh Lubana and Robert P. Dick and Hidenori Tanaka and Edward Grefenstette and Tim Rocktäschel and David Scott Krueger},
year={2023},
eprint={2311.12786},
archivePrefix={arXiv},
primaryClass={cs.LG}
}
Você também deve citar o artigo TinyStories:
@misc{eldan2023tinystories,
title={TinyStories: How Small Can Language Models Be and Still Speak Coherent English?},
author={Ronen Eldan and Yuanzhi Li},
year={2023},
eprint={2305.07759},
archivePrefix={arXiv},
primaryClass={cs.CL}
}