TRL documentation

ORPO Trainer

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v1.17.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

ORPO Trainer

model badge model badge

Visão geral

Odds Ratio Preference Optimization (ORPO) foi introduzido em ORPO: Monolithic Preference Optimization without Reference Model por Jiwoo Hong, Noah Lee e James Thorne.

O resumo do artigo é o seguinte:

Embora os algoritmos recentes de alinhamento de preferências para modelos de linguagem tenham demonstrado resultados promissores, o ajuste fino supervisionado (SFT) continua sendo imperativo para alcançar uma convergência bem-sucedida. Neste artigo, estudamos o papel crucial do SFT no contexto do alinhamento de preferências, enfatizando que uma penalidade menor para o estilo de geração desfavorecido é suficiente para o SFT alinhado a preferências. Com base nessa fundação, introduzimos um algoritmo monolítico de otimização de preferências baseado na razão de chances, livre de modelo de referência, simples e inovador, o ORPO, eliminando a necessidade de uma fase adicional de alinhamento de preferências. Demonstramos, tanto empiricamente quanto teoricamente, que a razão de chances é uma escolha sensata para contrastar estilos favorecidos e desfavorecidos durante o SFT, em tamanhos diversos, de 125M a 7B. Especificamente, o ajuste fino de Phi-2 (2.7B), Llama-2 (7B) e Mistral (7B) com ORPO, usando apenas o UltraFeedback, supera o desempenho de modelos de linguagem de estado da arte com mais de 7B e 13B parâmetros: alcançando até 12,20% no AlpacaEval_{2.0} (Figura 1), 66,19% no IFEval (nível de instrução, solto, Tabela 6) e 7,32 no MT-Bench (Figura 12). Liberamos o código e os checkpoints de modelos para Mistral-ORPO-alpha (7B) e Mistral-ORPO-beta (7B).

Ele estuda o papel crucial do SFT no contexto do alinhamento de preferências. Utilizando dados de preferências, o método postula que uma penalidade menor para a geração desfavorecida, juntamente com um forte sinal de adaptação à resposta escolhida por meio de um simples termo de razão de log-verossimilhança adicionado à perda NLL, é suficiente para um SFT alinhado a preferências.

Assim, o ORPO é um algoritmo de otimização de preferências sem modelo de referência, eliminando a necessidade de uma fase adicional de alinhamento de preferências, o que economiza computação e memória.

O código oficial pode ser encontrado em xfactlab/orpo.

Este método de pós-treinamento foi contribuído por Kashif Rasul, Lewis Tunstall e Alvaro Bartolome.

Início rápido

Este exemplo demonstra como treinar um modelo usando o método ORPO. Usamos o modelo Qwen 0.5B como modelo base. Usamos os dados de preferência do conjunto de dados UltraFeedback. Você pode visualizar os dados do conjunto de dados aqui:

Abaixo está o script para treinar o modelo:

# train_orpo.py
from datasets import load_dataset
from trl.experimental.orpo import ORPOConfig, ORPOTrainer
from transformers import AutoModelForCausalLM, AutoTokenizer

model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2-0.5B-Instruct")
tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2-0.5B-Instruct")
train_dataset = load_dataset("trl-lib/ultrafeedback_binarized", split="train")

training_args = ORPOConfig(output_dir="Qwen2-0.5B-ORPO")
trainer = ORPOTrainer(model=model, args=training_args, processing_class=tokenizer, train_dataset=train_dataset)
trainer.train()

Execute o script usando o seguinte comando:

torchrun --nproc_per_node 8 train_orpo.py

Distribuído em 8 GPUs, o treinamento leva aproximadamente 30 minutos. Você pode verificar o progresso do treinamento analisando o gráfico de recompensa. Uma tendência de aumento na margem de recompensa indica que o modelo está melhorando e gerando respostas melhores ao longo do tempo.

orpo qwen2 reward margin

Para ver como o modelo treinado se comporta, você pode usar o Transformers Chat CLI.

$ transformers chat trl-lib/Qwen2-0.5B-ORPO
<quentin_gallouedec>:
What is the best programming language?

<trl-lib/Qwen2-0.5B-ORPO>:
It's challenging to determine the best programming language as no one language is perfect, as the complexity of a task and the type of project are significant factors. Some popular languages include Java, Python, JavaScript, and
C++. If you have specific needs or requirements for a specific project, it's important to choose the language that best suits those needs.

Here are some other factors to consider when choosing a programming language for a project:

 • Language proficiency: A good programming language is more likely to be easy to understand and use, and will allow developers to collaborate on projects more efficiently.
 • Ease of use: There are tools and libraries available to make programming more accessible, so developers should choose a language that can help them get started easier.
 • Code readability: A clear and concise codebase should be easy to read and understand, especially when working with large projects.
 • Tool and framework support: There are numerous libraries available for Python, Java, and JavaScript, along with tools like IDEs and static code analysis tools.
 • Accessibility: Some languages and tools have features that make them more accessible to developers with disabilities, such as support for screen readers.
 • Version control: As your projects grow and complexity increases, version control tools can be beneficial for tracking changes.

Tipo de dataset esperado

ORPO requer um conjunto de dados de preferência. O experimental.orpo.ORPOTrainer suporta tanto o formato de conjunto de dados conversacional quanto o padrão. Quando fornecido com um conjunto de dados conversacional, o treinador aplicará automaticamente o modelo de chat ao conjunto de dados.

Embora o experimental.orpo.ORPOTrainer suporte prompts explícitos e implícitos, recomendamos o uso de prompts explícitos. Se um conjunto de dados com prompts implícitos for fornecido, o trainer extrairá automaticamente o prompt das colunas "chosen" e "rejected". Para mais informações, consulte a seção preference style.

Dicas de uso

Para Modelos Mixture of Experts: Habilitando a perda auxiliar

MOEs são mais eficientes quando a carga é distribuída de forma aproximadamente igual entre os especialistas.
Para garantir que treinemos MOEs de maneira semelhante durante o ajuste de preferências, é benéfico adicionar a perda auxiliar do balanceador de carga à perda final.

Esta opção é ativada definindo output_router_logits=True na configuração do modelo (por exemplo, MixtralConfig).
Para ajustar a contribuição da perda auxiliar para a perda total, use o hiperparâmetro router_aux_loss_coef=... (padrão: 0.001) na configuração do modelo.

Métricas registradas

Durante o treinamento e a avaliação, registramos as seguintes métricas:

  • rewards/chosen: as probabilidades log médias do modelo de política para as respostas escolhidas, escalonadas por beta
  • rewards/rejected: as probabilidades log médias do modelo de política para as respostas rejeitadas, escalonadas por beta
  • rewards/accuracies: média de quantas vezes as recompensas escolhidas são > que as recompensas rejeitadas correspondentes
  • rewards/margins: a diferença média entre as recompensas escolhidas e as recompensas rejeitadas correspondentes
  • log_odds_chosen: a média da razão de verossimilhança logarítmica das respostas escolhidas em relação às respostas rejeitadas
  • log_odds_ratio: a média de log(sigmoid(log_odds_chosen))
  • nll_loss: a perda média de log-verossimilhança negativa da parte de SFT da perda sobre as respostas escolhidas

ORPOTrainer

classe trl.experimental.orpo.ORPOTrainer

< >

( model: typing.Union[transformers.modeling_utils.PreTrainedModel, torch.nn.Module, str, NoneType] = Noneargs: trl.experimental.orpo.orpo_config.ORPOConfig | None = Nonedata_collator: collections.abc.Callable[[list[typing.Any]], dict[str, typing.Any]] | None = Nonetrain_dataset: datasets.arrow_dataset.Dataset | None = Noneeval_dataset: datasets.arrow_dataset.Dataset | dict[str, datasets.arrow_dataset.Dataset] | None = Noneprocessing_class: transformers.tokenization_utils_base.PreTrainedTokenizerBase | transformers.image_processing_utils.BaseImageProcessor | transformers.feature_extraction_utils.FeatureExtractionMixin | transformers.processing_utils.ProcessorMixin | None = Nonemodel_init: collections.abc.Callable[[], transformers.modeling_utils.PreTrainedModel] | None = Nonecallbacks: list[transformers.trainer_callback.TrainerCallback] | None = Noneoptimizers: tuple[torch.optim.Optimizer, torch.optim.lr_scheduler.LambdaLR] = (None, None)preprocess_logits_for_metrics: collections.abc.Callable[[torch.Tensor, torch.Tensor], torch.Tensor] | None = Nonepeft_config: PeftConfig | None = Nonecompute_metrics: collections.abc.Callable[[transformers.trainer_utils.EvalLoopOutput], dict] | None = None )

Parâmetros

  • model (PreTrainedModel) — O modelo a ser treinado, de preferência um AutoModelForSequenceClassification.
  • args (experimental.orpo.ORPOConfig) — Os argumentos de configuração do ORPO a serem usados para o treinamento.
  • data_collator (DataCollator) — O data collator a ser usado para o treinamento. Se None for especificado, o data collator padrão (experimental.utils.DPODataCollatorWithPadding) será utilizado, que irá aplicar padding nas sequências até o comprimento máximo das sequências no batch, dado um conjunto de dados de sequências em pares.
  • train_dataset (Dataset) — O conjunto de dados a ser usado para o treinamento.
  • eval_dataset (Dataset) — O conjunto de dados a ser usado para avaliação.
  • processing_class (PreTrainedTokenizerBase, BaseImageProcessor, FeatureExtractionMixin ou ProcessorMixin, opcional) — Classe de processamento usada para processar os dados. Se fornecida, será usada para processar automaticamente as entradas do modelo e será salva junto com o modelo para facilitar a reexecução de um treinamento interrompido ou a reutilização do modelo ajustado.
  • model_init (Callable[[], transformers.PreTrainedModel]) — O inicializador de modelo a ser usado para o treinamento. Se None for especificado, o inicializador de modelo padrão será usado.
  • callbacks (list[transformers.TrainerCallback]) — Os callbacks a serem usados para o treinamento.
  • optimizers (tuple[torch.optim.Optimizer, torch.optim.lr_scheduler.LambdaLR]) — O otimizador e o agendador a serem usados para o treinamento.
  • preprocess_logits_for_metrics (Callable[[torch.Tensor, torch.Tensor], torch.Tensor]) — A função a ser usada para pré-processar os logits antes de calcular as métricas.
  • peft_config (PeftConfig, opcional) — A configuração PEFT a ser usada para o treinamento. Se você passar uma configuração PEFT, o modelo será envolvido em um modelo PEFT.
  • compute_metrics (Callable[[EvalPrediction], dict], opcional) — A função a ser usada para calcular as métricas. Deve receber um EvalPrediction e retornar um dicionário de strings para valores de métricas.

Inicialize o ORPOTrainer.

treino

< >

( resume_from_checkpoint: str | bool | None = Nonetrial: optuna.Trial | dict[str, Any] | None = Noneignore_keys_for_eval: list[str] | None = None ) → ~trainer_utils.TrainOutput

Parâmetros

  • resume_from_checkpoint (str ou bool, opcional) — Se for um str, caminho local para um checkpoint salvo por uma instância anterior de Trainer. Se for um bool e for igual a True, carrega o último checkpoint em args.output_dir salvo por uma instância anterior de Trainer. Se presente, o treinamento será retomado a partir dos estados do modelo/otimizador/agendador carregados aqui.
  • trial (optuna.Trial ou dict[str, Any], opcional) — A execução do trial ou o dicionário de hiperparâmetros para a busca de hiperparâmetros.
  • ignore_keys_for_eval (list[str], opcional) — Uma lista de chaves na saída do seu modelo (se for um dicionário) que devem ser ignoradas ao coletar previsões para avaliação durante o treinamento.

Retorna

~trainer_utils.TrainOutput

Objeto contendo a contagem de etapas globais, a perda de treinamento e as métricas.

Ponto de entrada principal do treinamento.

save_model

< >

( output_dir: str | None = None_internal_call: bool = False )

Salvará o modelo, para que você possa recarregá-lo usando from_pretrained().

Salvará apenas a partir do processo principal.

push_to_hub

< >

( commit_message: str | None = 'End of training'blocking: bool = Truetoken: str | None = Nonerevision: str | None = None**kwargs )

Parâmetros

  • commit_message (str, opcional, padrão "End of training") — Mensagem a ser commitada durante o push.
  • blocking (bool, opcional, padrão True) — Se a função deve retornar apenas quando o git push tiver terminado.
  • token (str, opcional, padrão None) — Token com permissão de escrita para sobrescrever os argumentos originais do Trainer.
  • revision (str, opcional) — A revisão git de onde o commit será feito. O padrão é o topo do ramo “main”.
  • kwargs (dict[str, Any], opcional) — Argumentos de palavra-chave adicionais passados para ~Trainer.create_model_card.

Envie self.model e self.processing_class para o hub de modelos do 🤗 no repositório self.args.hub_model_id.

ORPOConfig

classe trl.experimental.orpo.ORPOConfig

< >

( output_dir: str | None = Noneper_device_train_batch_size: int = 8num_train_epochs: float = 3.0max_steps: int = -1learning_rate: float = 1e-06lr_scheduler_type: transformers.trainer_utils.SchedulerType | str = 'linear'lr_scheduler_kwargs: dict | str | None = Nonewarmup_steps: float = 0optim: transformers.training_args.OptimizerNames | str = 'adamw_torch_fused'optim_args: str | None = Noneweight_decay: float = 0.0adam_beta1: float = 0.9adam_beta2: float = 0.999adam_epsilon: float = 1e-08optim_target_modules: None | str | list[str] = Nonegradient_accumulation_steps: int = 1average_tokens_across_devices: bool = Truemax_grad_norm: float = 1.0label_smoothing_factor: float = 0.0bf16: bool | None = Nonefp16: bool = Falsebf16_full_eval: bool = Falsefp16_full_eval: bool = Falsetf32: bool | None = Nonegradient_checkpointing: bool = Truegradient_checkpointing_kwargs: dict[str, typing.Any] | str | None = Nonetorch_compile: bool = Falsetorch_compile_backend: str | None = Nonetorch_compile_mode: str | None = Noneuse_liger_kernel: bool = Falseliger_kernel_config: dict[str, bool] | None = Noneuse_cache: bool = Falseneftune_noise_alpha: float | None = Nonetorch_empty_cache_steps: int | None = Noneauto_find_batch_size: bool = Falselogging_strategy: transformers.trainer_utils.IntervalStrategy | str = 'steps'logging_steps: float = 10logging_first_step: bool = Falselog_on_each_node: bool = Truelogging_nan_inf_filter: bool = Trueinclude_num_input_tokens_seen: str | bool = 'no'log_level: str = 'passive'log_level_replica: str = 'warning'disable_tqdm: bool | None = Nonereport_to: None | str | list[str] = 'none'run_name: str | None = Noneproject: str = 'huggingface'trackio_space_id: str | None = Nonetrackio_bucket_id: str | None = Nonetrackio_static_space_id: typing.Union[str, NoneType, typing.Literal[False]] = Noneeval_strategy: transformers.trainer_utils.IntervalStrategy | str = 'no'eval_steps: float | None = Noneeval_delay: float = 0per_device_eval_batch_size: int = 8prediction_loss_only: bool = Falseeval_on_start: bool = Falseeval_do_concat_batches: bool = Trueeval_use_gather_object: bool = Falseeval_accumulation_steps: int | None = Noneinclude_for_metrics: list[str] = <factory>batch_eval_metrics: bool = Falsesave_only_model: bool = Falsesave_strategy: transformers.trainer_utils.SaveStrategy | str = 'steps'save_steps: float = 500save_on_each_node: bool = Falsesave_total_limit: int | None = Noneenable_jit_checkpoint: bool = Falsepush_to_hub: bool = Falsehub_token: str | None = Nonehub_private_repo: bool | None = Nonehub_model_id: str | None = Nonehub_strategy: transformers.trainer_utils.HubStrategy | str = 'every_save'hub_always_push: bool = Falsehub_revision: str | None = Noneload_best_model_at_end: bool = Falsemetric_for_best_model: str | None = Nonegreater_is_better: bool | None = Noneignore_data_skip: bool = Falserestore_callback_states_from_checkpoint: bool = Falsefull_determinism: bool = Falseseed: int = 42data_seed: int | None = Noneuse_cpu: bool = Falseaccelerator_config: dict | str | None = Noneparallelism_config: accelerate.parallelism_config.ParallelismConfig | None = Nonedataloader_drop_last: bool = Falsedataloader_num_workers: int = 0dataloader_pin_memory: bool = Truedataloader_persistent_workers: bool = Falsedataloader_prefetch_factor: int | None = Nonedataloader_multiprocessing_context: str | None = Nonedataloader_in_order: bool = Trueremove_unused_columns: bool = Truelabel_names: list[str] | None = Nonetrain_sampling_strategy: str = 'random'length_column_name: str = 'length'ddp_find_unused_parameters: bool | None = Noneddp_bucket_cap_mb: int | None = Noneddp_broadcast_buffers: bool | None = Noneddp_static_graph: bool | None = Noneddp_backend: str | None = Noneddp_timeout: int = 1800fsdp: str | None = Nonefsdp_config: dict[str, typing.Any] | str | None = Nonedeepspeed: dict | str | None = Nonedebug: str | list[transformers.debug_utils.DebugOption] = ''skip_memory_metrics: bool = Truedo_train: bool = Falsedo_eval: bool = Falsedo_predict: bool = Falseresume_from_checkpoint: str | None = Nonelocal_rank: int = -1max_length: int | None = 1024max_completion_length: int | None = Nonebeta: float = 0.1disable_dropout: bool = Truepadding_value: int | None = Nonegenerate_during_eval: bool = Falseis_encoder_decoder: bool | None = Nonemodel_init_kwargs: dict[str, typing.Any] | str | None = Nonetrust_remote_code: bool = Falsedataset_num_proc: int | None = None )

Parâmetros

  • max_length (int ou None, opcional, padrão 1024) — Comprimento máximo das sequências (prompt + completion) no lote. Este argumento é obrigatório se você quiser usar o data collator padrão.
  • max_completion_length (int, opcional) — Comprimento máximo da conclusão. Este argumento é obrigatório se você deseja usar o data collator padrão e seu modelo for um encoder-decoder.
  • beta (float, opcional, padrão 0.1) — Parâmetro que controla o peso relativo da perda de razão na perda ORPO. No artigo, é denotado por λ. No código, é denotado por alpha.
  • disable_dropout (bool, opcional, padrão True) — Se deve desabilitar o dropout no modelo.
  • padding_value (int, opcional) — Valor de padding a ser usado. Se None, o valor de padding do tokenizer é utilizado.
  • generate_during_eval (bool, opcional, padrão False) — Se True, gera e registra as conclusões do modelo no W&B ou Comet durante a avaliação.
  • is_encoder_decoder (bool, opcional) — Ao usar o argumento model_init (chamável) para instanciar o modelo em vez do argumento model, você precisa especificar se o modelo retornado pelo chamável é um modelo encoder-decoder.
  • model_init_kwargs (dict[str, Any], opcional) — Argumentos de palavra-chave para passar a AutoModelForCausalLM.from_pretrained ao instanciar o modelo a partir de uma string. O valor de revision também é usado ao carregar a classe de processamento.
  • trust_remote_code (bool, opcional, padrão False) — Se permite carregar modelos que incluem código Python personalizado do Hub. Encaminhado para from_pretrained.
  • dataset_num_proc (int, opcional) — Número de processos a serem usados para processar o conjunto de dados.

Classe de configuração para o experimental.orpo.ORPOTrainer.

Esta classe inclui apenas os parâmetros específicos para o treinamento ORPO. Para a lista completa de argumentos de treinamento, consulte a documentação de TrainingArguments. Observe que os valores padrão nesta classe podem diferir dos presentes em TrainingArguments.

Usando HfArgumentParser, podemos transformar essa classe em argumentos argparse que podem ser especificados na linha de comando.

Esses parâmetros possuem valores padrão diferentes de TrainingArguments:

  • logging_steps: O valor padrão é 10 em vez de 500.
  • gradient_checkpointing: O padrão é True em vez de False.
  • bf16: Padrão é True se fp16 não estiver definido, em vez de False.
  • learning_rate: O valor padrão é 1e-6 em vez de 5e-5.
Update on GitHub