This repository presents the source code of "DiaTool-DPO: Multi-Turn Direct Preference Optimization for Tool-Augmented Large Language Models", which is accepted at SIGDIAL 2025.
This work utilizes functionary chat template and trl to implement multi-turn DPO for tool-augmented LLMs.
The multi-turn DPO algorithm implemented in this repo is also applicable to other applications other than tool-augmented LLMs.
Understanding the value of joyful conversations, Kakao hopes this release will aid researchers working on multi-turn dialogue patterns in LLMs
@inproceedings{jung2025diatool,
title = {DiaTool-DPO: Multi-Turn Direct Preference Optimization for Tool-Augmented Large Language Models},
author = {Jung, Sunghee and Lee, Donghun and Lee, Shinbok and Seo, Gaeun and Lee, Daniel and Ko, Byeongil and Cho, Junrae and Kim, Kihyun and Kim, Eunggyun and Shin, Myeongcheol},
booktitle = {Proceedings of the 26th Annual Meeting of the Special Interest Group on Discourse and Dialogue (SIGDIAL 2025)},
year = {2025},
address = {Avignon, France}
}
@misc{vonwerra2022trl,
author = {Leandro von Werra and Younes Belkada and Lewis Tunstall and Edward Beeching and Tristan Thrush and Nathan Lambert and Shengyi Huang},
title = {TRL: Transformer Reinforcement Learning},
year = {2020},
publisher = {GitHub},
journal = {GitHub repository},
howpublished = {\url{https://github.com/huggingface/trl}}
}
@software{MeetKai_Functionary_2024,
author = {MeetKai},
title = {Functionary},
year = {2024},
url = {https://github.com/MeetKai/functionary},
version = {1.0.0}
}
The trl library is a full stack tool to fine-tune and align transformer language and diffusion models using methods such as Supervised Fine-tuning step (SFT), Reward Modeling (RM) and the Proximal Policy Optimization (PPO) as well as Direct Preference Optimization (DPO).
The library is built on top of the transformers library and thus allows to use any model architecture available there.
Efficient and scalable:
accelerate is the backbone of trl which allows to scale model training from a single GPU to a large scale multi-node cluster with methods such as DDP and DeepSpeed.PEFT is fully integrated and allows to train even the largest models on modest hardware with quantisation and methods such as LoRA or QLoRA.unsloth is also integrated and allows to significantly speed up training with dedicated kernels.CLI: With the CLI you can fine-tune and chat with LLMs without writing any code using a single command and a flexible config system.Trainers: The Trainer classes are an abstraction to apply many fine-tuning methods with ease such as the SFTTrainer, DPOTrainer, RewardTrainer, PPOTrainer, CPOTrainer, and ORPOTrainer.AutoModels: The AutoModelForCausalLMWithValueHead & AutoModelForSeq2SeqLMWithValueHead classes add an additional value head to the model which allows to train them with RL algorithms such as PPO.Examples: Train GPT2 to generate positive movie reviews with a BERT sentiment classifier, full RLHF using adapters only, train GPT-j to be less toxic, StackLlama example, etc. following the examples.Install the library with pip:
pip install trl
If you want to use the latest features before an official release you can install from source:
pip install git+https://github.com/huggingface/trl.git
If you want to use the examples you can clone the repository with the following command:
git clone https://github.com/huggingface/trl.git
You can use TRL Command Line Interface (CLI) to quickly get started with Supervised Fine-tuning (SFT), Direct Preference Optimization (DPO) and test your aligned model with the chat CLI:
SFT:
trl sft --model_name_or_path facebook/opt-125m --dataset_name imdb --output_dir opt-sft-imdb
DPO:
trl dpo --model_name_or_path facebook/opt-125m --dataset_name trl-internal-testing/hh-rlhf-helpful-base-trl-style --output_dir opt-sft-hh-rlhf
Chat:
trl chat --model_name_or_path Qwen/Qwen1.5-0.5B-Chat
Read more about CLI in the relevant documentation section or use --help for more details.
For more flexibility and control over the training, you can use the dedicated trainer classes to fine-tune the model in Python.
SFTTrainerThis is a basic example of how to use the SFTTrainer from the library. The SFTTrainer is a light wrapper around the transformers Trainer to easily fine-tune language models or adapters on a custom dataset.
# imports
from datasets import load_dataset
from trl import SFTTrainer
# get dataset
dataset = load_dataset("imdb", split="train")
# get trainer
trainer = SFTTrainer(
"facebook/opt-350m",
train_dataset=dataset,
dataset_text_field="text",
max_seq_length=512,
)
# train
trainer.train()
RewardTrainerThis is a basic example of how to use the RewardTrainer from the library. The RewardTrainer is a wrapper around the transformers Trainer to easily fine-tune reward models or adapters on a custom preference dataset.
# imports
from transformers import AutoModelForSequenceClassification, AutoTokenizer
from trl import RewardTrainer
# load model and dataset - dataset needs to be in a specific format
model = AutoModelForSequenceClassification.from_pretrained("gpt2", num_labels=1)
tokenizer = AutoTokenizer.from_pretrained("gpt2")
...
# load trainer
trainer = RewardTrainer(
model=model,
tokenizer=tokenizer,
train_dataset=dataset,
)
# train
trainer.train()
PPOTrainerThis is a basic example of how to use the PPOTrainer from the library. Based on a query the language model creates a response which is then evaluated. The evaluation could be a human in the loop or another model's output.
# imports
import torch
from transformers import AutoTokenizer
from trl import PPOTrainer, PPOConfig, AutoModelForCausalLMWithValueHead, create_reference_model
from trl.core import respond_to_batch
# get models
model = AutoModelForCausalLMWithValueHead.from_pretrained('gpt2')
ref_model = create_reference_model(model)
tokenizer = AutoTokenizer.from_pretrained('gpt2')
tokenizer.pad_token = tokenizer.eos_token
# initialize trainer
ppo_config = PPOConfig(batch_size=1, mini_batch_size=1)
# encode a query
query_txt = "This morning I went to the "
query_tensor = tokenizer.encode(query_txt, return_tensors="pt")
# get model response
response_tensor = respond_to_batch(model, query_tensor)
# create a ppo trainer
ppo_trainer = PPOTrainer(ppo_config, model, ref_model, tokenizer)
# define a reward for response
# (this could be any reward such as human feedback or output from another model)
reward = [torch.tensor(1.0)]
# train model for one step with ppo
train_stats = ppo_trainer.step([query_tensor[0]], [response_tensor[0]], reward)
DPOTrainerDPOTrainer is a trainer that uses Direct Preference Optimization algorithm. This is a basic example of how to use the DPOTrainer from the library. The DPOTrainer is a wrapper around the transformers Trainer to easily fine-tune reward models or adapters on a custom preference dataset.
# imports
from transformers import AutoModelForCausalLM, AutoTokenizer
from trl import DPOTrainer
# load model and dataset - dataset needs to be in a specific format
model = AutoModelForCausalLM.from_pretrained("gpt2")
tokenizer = AutoTokenizer.from_pretrained("gpt2")
...
# load trainer
trainer = DPOTrainer(
model=model,
tokenizer=tokenizer,
train_dataset=dataset,
)
# train
trainer.train()
If you want to contribute to trl or customizing it to your needs make sure to read the contribution guide and make sure you make a dev install:
git clone https://github.com/huggingface/trl.git
cd trl/
make dev
The PPO implementation largely follows the structure introduced in the paper "Fine-Tuning Language Models from Human Preferences" by D. Ziegler et al. [paper, code].
DPO is based on the original implementation of "Direct Preference Optimization: Your Language Model is Secretly a Reward Model" by E. Mitchell et al. [paper, code]
@misc{vonwerra2022trl,
author = {Leandro von Werra and Younes Belkada and Lewis Tunstall and Edward Beeching and Tristan Thrush and Nathan Lambert and Shengyi Huang},
title = {TRL: Transformer Reinforcement Learning},
year = {2020},
publisher = {GitHub},
journal = {GitHub repository},
howpublished = {\url{https://github.com/huggingface/trl}}
}
| Argument | Meaning | Default value if not specified |
|---|---|---|
| gamma | reward scaling factor | 0.5 |
| margin | reward gap subtraction | 0.5 |
cd ~/diatool-dpo
python -u -m accelerate.commands.launch
--config_file=./examples/accelerate_configs/deepspeed_zero3.yaml
--num_processes 8
./examples/scripts/diatool_dpo.py
--dataset_name={dataset_path}
--model_name_or_path={model_name_or_path_to_start_train}
--per_device_train_batch_size
1
--learning_rate
1e-7
--gradient_accumulation_steps
1
--logging_steps
10
--eval_steps
10
--output_dir={model_save_dir}
--warmup_steps
150
--report_to
wandb
--bf16
--logging_first_step
--no_remove_unused_columns
--max_length
8192
--max_prompt_length
4096
--do_eval
True
--eval_strategy
steps
--save_strategy
epoch
--save_steps
1
--beta
0.5
--gamma
0.5
--margin
2.0
--num_train_epochs
1.0
We evaluated our work with FunctionChat-Bench. Our DiaTool-DPO approach achieved 44% improvement in slot-filling and 9.6% improvement in relevance over the SFT-only baseline. It reaches 94.8% of the slot performance of GPT-4o. It also achieves 123.5% of the relevance score of GPT-4o-mini and 91.3% of the relevance score of GPT-4o. Further details about experiments and evaluations are included in our paper. https://arxiv.org/abs/2504.02882
| Model | Call | Competion | Slot | Relevance | Avg(micro) | Avg(macro) |
|---|---|---|---|---|---|---|
| SFT-Only | 0.843 | 0.957 | 0.639 | 0.826 | 0.844 | 0.816 |
| SFT + DiaTool-DPO | 0.857 | 0.929 | 0.917 | 0.913 | 0.905 | 0.904 |
| GPT-4o-mini-2024-07-18 | 0.929 | 0.971 | 0.972 | 0.739 | 0.920 | 0.903 |
| GPT-4o-2024-08-06 | 0.914 | 0.926 | 0.972 | 1.000 | 0.925 | 0.953 |
License This software is licensed under the Apache 2 license, quoted below.
Copyright 2025 Kakao Corp. http://www.kakaocorp.com
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this project except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
This repository presents the source code of "DiaTool-DPO: Multi-Turn Direct Preference Optimization for Tool-Augmented Large Language Models", which is accepted at SIGDIAL 2025.
This work utilizes functionary chat template and trl to implement multi-turn DPO for tool-augmented LLMs.
The multi-turn DPO algorithm implemented in this repo is also applicable to other applications other than tool-augmented LLMs.
Understanding the value of joyful conversations, Kakao hopes this release will aid researchers working on multi-turn dialogue patterns in LLMs
@inproceedings{jung2025diatool,
title = {DiaTool-DPO: Multi-Turn Direct Preference Optimization for Tool-Augmented Large Language Models},
author = {Jung, Sunghee and Lee, Donghun and Lee, Shinbok and Seo, Gaeun and Lee, Daniel and Ko, Byeongil and Cho, Junrae and Kim, Kihyun and Kim, Eunggyun and Shin, Myeongcheol},
booktitle = {Proceedings of the 26th Annual Meeting of the Special Interest Group on Discourse and Dialogue (SIGDIAL 2025)},
year = {2025},
address = {Avignon, France}
}
@misc{vonwerra2022trl,
author = {Leandro von Werra and Younes Belkada and Lewis Tunstall and Edward Beeching and Tristan Thrush and Nathan Lambert and Shengyi Huang},
title = {TRL: Transformer Reinforcement Learning},
year = {2020},
publisher = {GitHub},
journal = {GitHub repository},
howpublished = {\url{https://github.com/huggingface/trl}}
}
@software{MeetKai_Functionary_2024,
author = {MeetKai},
title = {Functionary},
year = {2024},
url = {https://github.com/MeetKai/functionary},
version = {1.0.0}
}
The trl library is a full stack tool to fine-tune and align transformer language and diffusion models using methods such as Supervised Fine-tuning step (SFT), Reward Modeling (RM) and the Proximal Policy Optimization (PPO) as well as Direct Preference Optimization (DPO).
The library is built on top of the transformers library and thus allows to use any model architecture available there.
Efficient and scalable:
accelerate is the backbone of trl which allows to scale model training from a single GPU to a large scale multi-node cluster with methods such as DDP and DeepSpeed.PEFT is fully integrated and allows to train even the largest models on modest hardware with quantisation and methods such as LoRA or QLoRA.unsloth is also integrated and allows to significantly speed up training with dedicated kernels.CLI: With the CLI you can fine-tune and chat with LLMs without writing any code using a single command and a flexible config system.Trainers: The Trainer classes are an abstraction to apply many fine-tuning methods with ease such as the SFTTrainer, DPOTrainer, RewardTrainer, PPOTrainer, CPOTrainer, and ORPOTrainer.AutoModels: The AutoModelForCausalLMWithValueHead & AutoModelForSeq2SeqLMWithValueHead classes add an additional value head to the model which allows to train them with RL algorithms such as PPO.Examples: Train GPT2 to generate positive movie reviews with a BERT sentiment classifier, full RLHF using adapters only, train GPT-j to be less toxic, StackLlama example, etc. following the examples.Install the library with pip:
pip install trl
If you want to use the latest features before an official release you can install from source:
pip install git+https://github.com/huggingface/trl.git
If you want to use the examples you can clone the repository with the following command:
git clone https://github.com/huggingface/trl.git
You can use TRL Command Line Interface (CLI) to quickly get started with Supervised Fine-tuning (SFT), Direct Preference Optimization (DPO) and test your aligned model with the chat CLI:
SFT:
trl sft --model_name_or_path facebook/opt-125m --dataset_name imdb --output_dir opt-sft-imdb
DPO:
trl dpo --model_name_or_path facebook/opt-125m --dataset_name trl-internal-testing/hh-rlhf-helpful-base-trl-style --output_dir opt-sft-hh-rlhf
Chat:
trl chat --model_name_or_path Qwen/Qwen1.5-0.5B-Chat
Read more about CLI in the relevant documentation section or use --help for more details.
For more flexibility and control over the training, you can use the dedicated trainer classes to fine-tune the model in Python.
SFTTrainerThis is a basic example of how to use the SFTTrainer from the library. The SFTTrainer is a light wrapper around the transformers Trainer to easily fine-tune language models or adapters on a custom dataset.
# imports
from datasets import load_dataset
from trl import SFTTrainer
# get dataset
dataset = load_dataset("imdb", split="train")
# get trainer
trainer = SFTTrainer(
"facebook/opt-350m",
train_dataset=dataset,
dataset_text_field="text",
max_seq_length=512,
)
# train
trainer.train()
RewardTrainerThis is a basic example of how to use the RewardTrainer from the library. The RewardTrainer is a wrapper around the transformers Trainer to easily fine-tune reward models or adapters on a custom preference dataset.
# imports
from transformers import AutoModelForSequenceClassification, AutoTokenizer
from trl import RewardTrainer
# load model and dataset - dataset needs to be in a specific format
model = AutoModelForSequenceClassification.from_pretrained("gpt2", num_labels=1)
tokenizer = AutoTokenizer.from_pretrained("gpt2")
...
# load trainer
trainer = RewardTrainer(
model=model,
tokenizer=tokenizer,
train_dataset=dataset,
)
# train
trainer.train()
PPOTrainerThis is a basic example of how to use the PPOTrainer from the library. Based on a query the language model creates a response which is then evaluated. The evaluation could be a human in the loop or another model's output.
# imports
import torch
from transformers import AutoTokenizer
from trl import PPOTrainer, PPOConfig, AutoModelForCausalLMWithValueHead, create_reference_model
from trl.core import respond_to_batch
# get models
model = AutoModelForCausalLMWithValueHead.from_pretrained('gpt2')
ref_model = create_reference_model(model)
tokenizer = AutoTokenizer.from_pretrained('gpt2')
tokenizer.pad_token = tokenizer.eos_token
# initialize trainer
ppo_config = PPOConfig(batch_size=1, mini_batch_size=1)
# encode a query
query_txt = "This morning I went to the "
query_tensor = tokenizer.encode(query_txt, return_tensors="pt")
# get model response
response_tensor = respond_to_batch(model, query_tensor)
# create a ppo trainer
ppo_trainer = PPOTrainer(ppo_config, model, ref_model, tokenizer)
# define a reward for response
# (this could be any reward such as human feedback or output from another model)
reward = [torch.tensor(1.0)]
# train model for one step with ppo
train_stats = ppo_trainer.step([query_tensor[0]], [response_tensor[0]], reward)
DPOTrainerDPOTrainer is a trainer that uses Direct Preference Optimization algorithm. This is a basic example of how to use the DPOTrainer from the library. The DPOTrainer is a wrapper around the transformers Trainer to easily fine-tune reward models or adapters on a custom preference dataset.
# imports
from transformers import AutoModelForCausalLM, AutoTokenizer
from trl import DPOTrainer
# load model and dataset - dataset needs to be in a specific format
model = AutoModelForCausalLM.from_pretrained("gpt2")
tokenizer = AutoTokenizer.from_pretrained("gpt2")
...
# load trainer
trainer = DPOTrainer(
model=model,
tokenizer=tokenizer,
train_dataset=dataset,
)
# train
trainer.train()
If you want to contribute to trl or customizing it to your needs make sure to read the contribution guide and make sure you make a dev install:
git clone https://github.com/huggingface/trl.git
cd trl/
make dev
The PPO implementation largely follows the structure introduced in the paper "Fine-Tuning Language Models from Human Preferences" by D. Ziegler et al. [paper, code].
DPO is based on the original implementation of "Direct Preference Optimization: Your Language Model is Secretly a Reward Model" by E. Mitchell et al. [paper, code]
@misc{vonwerra2022trl,
author = {Leandro von Werra and Younes Belkada and Lewis Tunstall and Edward Beeching and Tristan Thrush and Nathan Lambert and Shengyi Huang},
title = {TRL: Transformer Reinforcement Learning},
year = {2020},
publisher = {GitHub},
journal = {GitHub repository},
howpublished = {\url{https://github.com/huggingface/trl}}
}
| Argument | Meaning | Default value if not specified |
|---|---|---|
| gamma | reward scaling factor | 0.5 |
| margin | reward gap subtraction | 0.5 |
cd ~/diatool-dpo
python -u -m accelerate.commands.launch
--config_file=./examples/accelerate_configs/deepspeed_zero3.yaml
--num_processes 8
./examples/scripts/diatool_dpo.py
--dataset_name={dataset_path}
--model_name_or_path={model_name_or_path_to_start_train}
--per_device_train_batch_size
1
--learning_rate
1e-7
--gradient_accumulation_steps
1
--logging_steps
10
--eval_steps
10
--output_dir={model_save_dir}
--warmup_steps
150
--report_to
wandb
--bf16
--logging_first_step
--no_remove_unused_columns
--max_length
8192
--max_prompt_length
4096
--do_eval
True
--eval_strategy
steps
--save_strategy
epoch
--save_steps
1
--beta
0.5
--gamma
0.5
--margin
2.0
--num_train_epochs
1.0
We evaluated our work with FunctionChat-Bench. Our DiaTool-DPO approach achieved 44% improvement in slot-filling and 9.6% improvement in relevance over the SFT-only baseline. It reaches 94.8% of the slot performance of GPT-4o. It also achieves 123.5% of the relevance score of GPT-4o-mini and 91.3% of the relevance score of GPT-4o. Further details about experiments and evaluations are included in our paper. https://arxiv.org/abs/2504.02882
| Model | Call | Competion | Slot | Relevance | Avg(micro) | Avg(macro) |
|---|---|---|---|---|---|---|
| SFT-Only | 0.843 | 0.957 | 0.639 | 0.826 | 0.844 | 0.816 |
| SFT + DiaTool-DPO | 0.857 | 0.929 | 0.917 | 0.913 | 0.905 | 0.904 |
| GPT-4o-mini-2024-07-18 | 0.929 | 0.971 | 0.972 | 0.739 | 0.920 | 0.903 |
| GPT-4o-2024-08-06 | 0.914 | 0.926 | 0.972 | 1.000 | 0.925 | 0.953 |
License This software is licensed under the Apache 2 license, quoted below.
Copyright 2025 Kakao Corp. http://www.kakaocorp.com
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this project except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.