Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ModelZoo
DISC-FinLLM_pytorch
Commits
afe180a6
Commit
afe180a6
authored
May 21, 2024
by
wanglch
Browse files
Initial commit
parents
Pipeline
#1006
canceled with stages
Changes
258
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1580 additions
and
0 deletions
+1580
-0
LLaMA-Factory/src/llmtuner/train/rm/trainer.py
LLaMA-Factory/src/llmtuner/train/rm/trainer.py
+99
-0
LLaMA-Factory/src/llmtuner/train/rm/workflow.py
LLaMA-Factory/src/llmtuner/train/rm/workflow.py
+79
-0
LLaMA-Factory/src/llmtuner/train/sft/__init__.py
LLaMA-Factory/src/llmtuner/train/sft/__init__.py
+4
-0
LLaMA-Factory/src/llmtuner/train/sft/metric.py
LLaMA-Factory/src/llmtuner/train/sft/metric.py
+61
-0
LLaMA-Factory/src/llmtuner/train/sft/trainer.py
LLaMA-Factory/src/llmtuner/train/sft/trainer.py
+100
-0
LLaMA-Factory/src/llmtuner/train/sft/workflow.py
LLaMA-Factory/src/llmtuner/train/sft/workflow.py
+101
-0
LLaMA-Factory/src/llmtuner/train/tuner.py
LLaMA-Factory/src/llmtuner/train/tuner.py
+91
-0
LLaMA-Factory/src/llmtuner/train/utils.py
LLaMA-Factory/src/llmtuner/train/utils.py
+120
-0
LLaMA-Factory/src/llmtuner/webui/__init__.py
LLaMA-Factory/src/llmtuner/webui/__init__.py
+4
-0
LLaMA-Factory/src/llmtuner/webui/chatter.py
LLaMA-Factory/src/llmtuner/webui/chatter.py
+147
-0
LLaMA-Factory/src/llmtuner/webui/common.py
LLaMA-Factory/src/llmtuner/webui/common.py
+113
-0
LLaMA-Factory/src/llmtuner/webui/components/__init__.py
LLaMA-Factory/src/llmtuner/webui/components/__init__.py
+16
-0
LLaMA-Factory/src/llmtuner/webui/components/chatbot.py
LLaMA-Factory/src/llmtuner/webui/components/chatbot.py
+60
-0
LLaMA-Factory/src/llmtuner/webui/components/data.py
LLaMA-Factory/src/llmtuner/webui/components/data.py
+93
-0
LLaMA-Factory/src/llmtuner/webui/components/eval.py
LLaMA-Factory/src/llmtuner/webui/components/eval.py
+76
-0
LLaMA-Factory/src/llmtuner/webui/components/export.py
LLaMA-Factory/src/llmtuner/webui/components/export.py
+105
-0
LLaMA-Factory/src/llmtuner/webui/components/infer.py
LLaMA-Factory/src/llmtuner/webui/components/infer.py
+36
-0
LLaMA-Factory/src/llmtuner/webui/components/top.py
LLaMA-Factory/src/llmtuner/webui/components/top.py
+61
-0
LLaMA-Factory/src/llmtuner/webui/components/train.py
LLaMA-Factory/src/llmtuner/webui/components/train.py
+187
-0
LLaMA-Factory/src/llmtuner/webui/css.py
LLaMA-Factory/src/llmtuner/webui/css.py
+27
-0
No files found.
LLaMA-Factory/src/llmtuner/train/rm/trainer.py
0 → 100644
View file @
afe180a6
import
json
import
os
from
typing
import
TYPE_CHECKING
,
Dict
,
List
,
Optional
,
Tuple
,
Union
import
torch
from
transformers
import
Trainer
from
...extras.logging
import
get_logger
if
TYPE_CHECKING
:
from
transformers.modeling_utils
import
PreTrainedModel
from
transformers.trainer
import
PredictionOutput
logger
=
get_logger
(
__name__
)
class
PairwiseTrainer
(
Trainer
):
r
"""
Inherits PeftTrainer to compute pairwise loss.
"""
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
().
__init__
(
*
args
,
**
kwargs
)
self
.
can_return_loss
=
True
# override property to return eval_loss
def
compute_loss
(
self
,
model
:
"PreTrainedModel"
,
inputs
:
Dict
[
str
,
torch
.
Tensor
],
return_outputs
:
Optional
[
bool
]
=
False
)
->
Union
[
torch
.
Tensor
,
Tuple
[
torch
.
Tensor
,
List
[
torch
.
Tensor
]]]:
r
"""
Computes pairwise loss. The first n examples are chosen and the last n examples are rejected.
Subclass and override to inject custom behavior.
Note that the first element will be removed from the output tuple.
See: https://github.com/huggingface/transformers/blob/v4.30.2/src/transformers/trainer.py#L3509
"""
# Compute rewards
_
,
_
,
values
=
model
(
**
inputs
,
output_hidden_states
=
True
,
return_dict
=
True
)
unwrapped_model
:
"PreTrainedModel"
=
self
.
accelerator
.
unwrap_model
(
self
.
model
)
if
getattr
(
unwrapped_model
.
config
,
"model_type"
,
None
)
==
"chatglm"
:
values
=
torch
.
transpose
(
values
,
0
,
1
)
# Split the inputs and rewards into two parts, chosen and rejected
batch_size
=
inputs
[
"input_ids"
].
size
(
0
)
//
2
chosen_input_ids
,
rejected_input_ids
=
inputs
[
"input_ids"
][:
batch_size
],
inputs
[
"input_ids"
][
batch_size
:]
chosen_rewards
,
rejected_rewards
=
values
[:
batch_size
],
values
[
batch_size
:]
chosen_scores
,
rejected_scores
=
[],
[]
# Compute pairwise loss. Only backprop on the different tokens before padding
# Inspired by: https://github.com/CarperAI/trlx/blob/main/examples/summarize_rlhf/reward_model/reward_model.py
loss
=
0
for
i
in
range
(
batch_size
):
chosen_length
=
(
chosen_input_ids
[
i
]
!=
self
.
tokenizer
.
pad_token_id
).
nonzero
()[
-
1
]
+
1
rejected_length
=
(
rejected_input_ids
[
i
]
!=
self
.
tokenizer
.
pad_token_id
).
nonzero
()[
-
1
]
+
1
check_divergence
=
(
chosen_input_ids
[
i
]
!=
rejected_input_ids
[
i
]).
nonzero
()
if
len
(
check_divergence
)
==
0
:
end_index
=
chosen_length
div_index
=
end_index
-
1
else
:
end_index
=
max
(
chosen_length
,
rejected_length
)
div_index
=
check_divergence
[
0
]
assert
div_index
>
0
chosen_trunc_rewards
=
chosen_rewards
[
i
,
div_index
:
end_index
]
rejected_trunc_rewards
=
rejected_rewards
[
i
,
div_index
:
end_index
]
if
return_outputs
:
# use the score on the last token except pad token for inference
chosen_scores
.
append
(
chosen_rewards
[
i
,
chosen_length
-
1
])
rejected_scores
.
append
(
rejected_rewards
[
i
,
rejected_length
-
1
])
loss
+=
-
torch
.
nn
.
functional
.
logsigmoid
(
chosen_trunc_rewards
-
rejected_trunc_rewards
).
mean
()
loss
=
loss
/
batch_size
if
return_outputs
:
chosen_scores
,
rejected_scores
=
torch
.
stack
(
chosen_scores
),
torch
.
stack
(
rejected_scores
)
return
loss
,
[
loss
,
chosen_scores
,
rejected_scores
]
return
loss
def
save_predictions
(
self
,
predict_results
:
"PredictionOutput"
)
->
None
:
r
"""
Saves model predictions to `output_dir`.
A custom behavior that not contained in Seq2SeqTrainer.
"""
if
not
self
.
is_world_process_zero
():
return
output_prediction_file
=
os
.
path
.
join
(
self
.
args
.
output_dir
,
"generated_predictions.jsonl"
)
logger
.
info
(
f
"Saving prediction results to
{
output_prediction_file
}
"
)
chosen_scores
,
rejected_scores
=
predict_results
.
predictions
with
open
(
output_prediction_file
,
"w"
,
encoding
=
"utf-8"
)
as
writer
:
res
:
List
[
str
]
=
[]
for
c_score
,
r_score
in
zip
(
chosen_scores
,
rejected_scores
):
res
.
append
(
json
.
dumps
({
"chosen"
:
round
(
float
(
c_score
),
2
),
"rejected"
:
round
(
float
(
r_score
),
2
)}))
writer
.
write
(
"
\n
"
.
join
(
res
))
LLaMA-Factory/src/llmtuner/train/rm/workflow.py
0 → 100644
View file @
afe180a6
# Inspired by: https://github.com/CarperAI/trlx/blob/main/examples/summarize_rlhf/reward_model/train_reward_model_gptj.py
from
typing
import
TYPE_CHECKING
,
List
,
Optional
from
transformers
import
Seq2SeqTrainingArguments
from
...data
import
get_dataset
,
split_dataset
from
...extras.callbacks
import
FixValueHeadModelCallback
from
...extras.misc
import
fix_valuehead_checkpoint
from
...extras.ploting
import
plot_loss
from
...model
import
load_model_and_tokenizer
from
...train.rm.collator
import
PairwiseDataCollatorWithPadding
from
...train.rm.metric
import
compute_accuracy
from
...train.rm.trainer
import
PairwiseTrainer
from
...train.utils
import
create_modelcard_and_push
if
TYPE_CHECKING
:
from
transformers
import
TrainerCallback
from
...hparams
import
DataArguments
,
FinetuningArguments
,
ModelArguments
def
run_rm
(
model_args
:
"ModelArguments"
,
data_args
:
"DataArguments"
,
training_args
:
"Seq2SeqTrainingArguments"
,
finetuning_args
:
"FinetuningArguments"
,
callbacks
:
Optional
[
List
[
"TrainerCallback"
]]
=
None
,
):
model
,
tokenizer
=
load_model_and_tokenizer
(
model_args
,
finetuning_args
,
training_args
.
do_train
,
add_valuehead
=
True
)
dataset
=
get_dataset
(
tokenizer
,
model_args
,
data_args
,
training_args
,
stage
=
"rm"
)
data_collator
=
PairwiseDataCollatorWithPadding
(
tokenizer
,
pad_to_multiple_of
=
8
)
# Update arguments
training_args_dict
=
training_args
.
to_dict
()
training_args_dict
.
update
(
dict
(
remove_unused_columns
=
False
))
# important for pairwise dataset
training_args
=
Seq2SeqTrainingArguments
(
**
training_args_dict
)
# Initialize our Trainer
trainer
=
PairwiseTrainer
(
model
=
model
,
args
=
training_args
,
tokenizer
=
tokenizer
,
data_collator
=
data_collator
,
callbacks
=
callbacks
+
[
FixValueHeadModelCallback
()],
compute_metrics
=
compute_accuracy
,
**
split_dataset
(
dataset
,
data_args
,
training_args
),
)
# Training
if
training_args
.
do_train
:
train_result
=
trainer
.
train
(
resume_from_checkpoint
=
training_args
.
resume_from_checkpoint
)
trainer
.
save_model
()
if
training_args
.
should_save
:
fix_valuehead_checkpoint
(
model
,
training_args
.
output_dir
,
training_args
.
save_safetensors
)
trainer
.
log_metrics
(
"train"
,
train_result
.
metrics
)
trainer
.
save_metrics
(
"train"
,
train_result
.
metrics
)
trainer
.
save_state
()
if
trainer
.
is_world_process_zero
()
and
finetuning_args
.
plot_loss
:
plot_loss
(
training_args
.
output_dir
,
keys
=
[
"loss"
,
"eval_loss"
])
# Evaluation
if
training_args
.
do_eval
:
metrics
=
trainer
.
evaluate
(
metric_key_prefix
=
"eval"
)
trainer
.
log_metrics
(
"eval"
,
metrics
)
trainer
.
save_metrics
(
"eval"
,
metrics
)
# Predict
if
training_args
.
do_predict
:
predict_results
=
trainer
.
predict
(
dataset
,
metric_key_prefix
=
"predict"
)
trainer
.
log_metrics
(
"predict"
,
predict_results
.
metrics
)
trainer
.
save_metrics
(
"predict"
,
predict_results
.
metrics
)
trainer
.
save_predictions
(
predict_results
)
# Create model card
create_modelcard_and_push
(
trainer
,
model_args
,
data_args
,
training_args
,
finetuning_args
)
LLaMA-Factory/src/llmtuner/train/sft/__init__.py
0 → 100644
View file @
afe180a6
from
.workflow
import
run_sft
__all__
=
[
"run_sft"
]
LLaMA-Factory/src/llmtuner/train/sft/metric.py
0 → 100644
View file @
afe180a6
from
dataclasses
import
dataclass
from
typing
import
TYPE_CHECKING
,
Dict
,
Sequence
,
Tuple
,
Union
import
numpy
as
np
from
...extras.constants
import
IGNORE_INDEX
from
...extras.packages
import
is_jieba_available
,
is_nltk_available
,
is_rouge_available
if
TYPE_CHECKING
:
from
transformers.tokenization_utils
import
PreTrainedTokenizer
if
is_jieba_available
():
import
jieba
if
is_nltk_available
():
from
nltk.translate.bleu_score
import
SmoothingFunction
,
sentence_bleu
if
is_rouge_available
():
from
rouge_chinese
import
Rouge
@
dataclass
class
ComputeMetrics
:
r
"""
Wraps the tokenizer into metric functions, used in Seq2SeqPeftTrainer.
"""
tokenizer
:
"PreTrainedTokenizer"
def
__call__
(
self
,
eval_preds
:
Sequence
[
Union
[
np
.
ndarray
,
Tuple
[
np
.
ndarray
]]])
->
Dict
[
str
,
float
]:
r
"""
Uses the model predictions to compute metrics.
"""
preds
,
labels
=
eval_preds
score_dict
=
{
"rouge-1"
:
[],
"rouge-2"
:
[],
"rouge-l"
:
[],
"bleu-4"
:
[]}
preds
=
np
.
where
(
preds
!=
IGNORE_INDEX
,
preds
,
self
.
tokenizer
.
pad_token_id
)
labels
=
np
.
where
(
labels
!=
IGNORE_INDEX
,
labels
,
self
.
tokenizer
.
pad_token_id
)
decoded_preds
=
self
.
tokenizer
.
batch_decode
(
preds
,
skip_special_tokens
=
True
)
decoded_labels
=
self
.
tokenizer
.
batch_decode
(
labels
,
skip_special_tokens
=
True
)
for
pred
,
label
in
zip
(
decoded_preds
,
decoded_labels
):
hypothesis
=
list
(
jieba
.
cut
(
pred
))
reference
=
list
(
jieba
.
cut
(
label
))
if
len
(
" "
.
join
(
hypothesis
).
split
())
==
0
or
len
(
" "
.
join
(
reference
).
split
())
==
0
:
result
=
{
"rouge-1"
:
{
"f"
:
0.0
},
"rouge-2"
:
{
"f"
:
0.0
},
"rouge-l"
:
{
"f"
:
0.0
}}
else
:
rouge
=
Rouge
()
scores
=
rouge
.
get_scores
(
" "
.
join
(
hypothesis
),
" "
.
join
(
reference
))
result
=
scores
[
0
]
for
k
,
v
in
result
.
items
():
score_dict
[
k
].
append
(
round
(
v
[
"f"
]
*
100
,
4
))
bleu_score
=
sentence_bleu
([
list
(
label
)],
list
(
pred
),
smoothing_function
=
SmoothingFunction
().
method3
)
score_dict
[
"bleu-4"
].
append
(
round
(
bleu_score
*
100
,
4
))
return
{
k
:
float
(
np
.
mean
(
v
))
for
k
,
v
in
score_dict
.
items
()}
LLaMA-Factory/src/llmtuner/train/sft/trainer.py
0 → 100644
View file @
afe180a6
import
json
import
os
from
typing
import
TYPE_CHECKING
,
Any
,
Dict
,
List
,
Optional
,
Tuple
,
Union
import
numpy
as
np
import
torch
import
torch.nn
as
nn
from
transformers
import
Seq2SeqTrainer
from
...extras.constants
import
IGNORE_INDEX
from
...extras.logging
import
get_logger
if
TYPE_CHECKING
:
from
transformers.trainer
import
PredictionOutput
logger
=
get_logger
(
__name__
)
class
CustomSeq2SeqTrainer
(
Seq2SeqTrainer
):
r
"""
Inherits PeftTrainer to compute generative metrics such as BLEU and ROUGE.
"""
def
prediction_step
(
self
,
model
:
nn
.
Module
,
inputs
:
Dict
[
str
,
Union
[
torch
.
Tensor
,
Any
]],
prediction_loss_only
:
bool
,
ignore_keys
:
Optional
[
List
[
str
]]
=
None
,
)
->
Tuple
[
Optional
[
float
],
Optional
[
torch
.
Tensor
],
Optional
[
torch
.
Tensor
]]:
r
"""
Removes the prompt part in the generated tokens.
Subclass and override to inject custom behavior.
"""
labels
=
inputs
[
"labels"
].
detach
().
clone
()
if
"labels"
in
inputs
else
None
# backup labels
if
self
.
args
.
predict_with_generate
:
assert
self
.
tokenizer
.
padding_side
==
"left"
,
"This method only accepts left-padded tensor."
prompt_len
,
label_len
=
inputs
[
"input_ids"
].
size
(
-
1
),
inputs
[
"labels"
].
size
(
-
1
)
if
prompt_len
>
label_len
:
inputs
[
"labels"
]
=
self
.
_pad_tensors_to_target_len
(
inputs
[
"labels"
],
inputs
[
"input_ids"
])
if
label_len
>
prompt_len
:
# truncate the labels instead of padding the inputs (llama2 fp16 compatibility)
inputs
[
"labels"
]
=
inputs
[
"labels"
][:,
:
prompt_len
]
loss
,
generated_tokens
,
_
=
super
().
prediction_step
(
# ignore the returned labels (may be truncated)
model
,
inputs
,
prediction_loss_only
=
prediction_loss_only
,
ignore_keys
=
ignore_keys
)
if
generated_tokens
is
not
None
and
self
.
args
.
predict_with_generate
:
generated_tokens
[:,
:
prompt_len
]
=
self
.
tokenizer
.
pad_token_id
generated_tokens
=
generated_tokens
.
contiguous
()
return
loss
,
generated_tokens
,
labels
def
_pad_tensors_to_target_len
(
self
,
src_tensor
:
torch
.
Tensor
,
tgt_tensor
:
torch
.
Tensor
)
->
torch
.
Tensor
:
r
"""
Pads the tensor to the same length as the target tensor.
"""
assert
self
.
tokenizer
.
pad_token_id
is
not
None
,
"Pad token is required."
padded_tensor
=
self
.
tokenizer
.
pad_token_id
*
torch
.
ones_like
(
tgt_tensor
)
padded_tensor
[:,
-
src_tensor
.
shape
[
-
1
]
:]
=
src_tensor
# adopt left-padding
return
padded_tensor
.
contiguous
()
# in contiguous memory
def
save_predictions
(
self
,
predict_results
:
"PredictionOutput"
)
->
None
:
r
"""
Saves model predictions to `output_dir`.
A custom behavior that not contained in Seq2SeqTrainer.
"""
if
not
self
.
is_world_process_zero
():
return
output_prediction_file
=
os
.
path
.
join
(
self
.
args
.
output_dir
,
"generated_predictions.jsonl"
)
logger
.
info
(
f
"Saving prediction results to
{
output_prediction_file
}
"
)
labels
=
np
.
where
(
predict_results
.
label_ids
!=
IGNORE_INDEX
,
predict_results
.
label_ids
,
self
.
tokenizer
.
pad_token_id
)
preds
=
np
.
where
(
predict_results
.
predictions
!=
IGNORE_INDEX
,
predict_results
.
predictions
,
self
.
tokenizer
.
pad_token_id
)
for
i
in
range
(
len
(
preds
)):
pad_len
=
np
.
nonzero
(
preds
[
i
]
!=
self
.
tokenizer
.
pad_token_id
)[
0
]
if
len
(
pad_len
):
preds
[
i
]
=
np
.
concatenate
(
(
preds
[
i
][
pad_len
[
0
]
:],
preds
[
i
][:
pad_len
[
0
]]),
axis
=-
1
)
# move pad token to last
decoded_labels
=
self
.
tokenizer
.
batch_decode
(
labels
,
skip_special_tokens
=
True
,
clean_up_tokenization_spaces
=
False
)
decoded_preds
=
self
.
tokenizer
.
batch_decode
(
preds
,
skip_special_tokens
=
True
,
clean_up_tokenization_spaces
=
True
)
with
open
(
output_prediction_file
,
"w"
,
encoding
=
"utf-8"
)
as
writer
:
res
:
List
[
str
]
=
[]
for
label
,
pred
in
zip
(
decoded_labels
,
decoded_preds
):
res
.
append
(
json
.
dumps
({
"label"
:
label
,
"predict"
:
pred
},
ensure_ascii
=
False
))
writer
.
write
(
"
\n
"
.
join
(
res
))
LLaMA-Factory/src/llmtuner/train/sft/workflow.py
0 → 100644
View file @
afe180a6
# Inspired by: https://github.com/huggingface/transformers/blob/v4.34.1/examples/pytorch/summarization/run_summarization.py
from
typing
import
TYPE_CHECKING
,
List
,
Optional
from
transformers
import
DataCollatorForSeq2Seq
,
Seq2SeqTrainingArguments
from
...data
import
get_dataset
,
split_dataset
from
...extras.constants
import
IGNORE_INDEX
from
...extras.misc
import
get_logits_processor
from
...extras.ploting
import
plot_loss
from
...model
import
load_model_and_tokenizer
from
...train.sft.metric
import
ComputeMetrics
from
...train.sft.trainer
import
CustomSeq2SeqTrainer
from
...train.utils
import
create_modelcard_and_push
if
TYPE_CHECKING
:
from
transformers
import
TrainerCallback
from
...hparams
import
DataArguments
,
FinetuningArguments
,
GeneratingArguments
,
ModelArguments
def
run_sft
(
model_args
:
"ModelArguments"
,
data_args
:
"DataArguments"
,
training_args
:
"Seq2SeqTrainingArguments"
,
finetuning_args
:
"FinetuningArguments"
,
generating_args
:
"GeneratingArguments"
,
callbacks
:
Optional
[
List
[
"TrainerCallback"
]]
=
None
,
):
model
,
tokenizer
=
load_model_and_tokenizer
(
model_args
,
finetuning_args
,
training_args
.
do_train
)
dataset
=
get_dataset
(
tokenizer
,
model_args
,
data_args
,
training_args
,
stage
=
"sft"
)
if
training_args
.
predict_with_generate
:
tokenizer
.
padding_side
=
"left"
# use left-padding in generation
if
getattr
(
model
,
"is_quantized"
,
False
)
and
not
training_args
.
do_train
:
setattr
(
model
,
"_hf_peft_config_loaded"
,
True
)
# hack here: make model compatible with prediction
data_collator
=
DataCollatorForSeq2Seq
(
tokenizer
=
tokenizer
,
pad_to_multiple_of
=
8
if
tokenizer
.
padding_side
==
"right"
else
None
,
# for shift short attention
label_pad_token_id
=
IGNORE_INDEX
if
data_args
.
ignore_pad_token_for_loss
else
tokenizer
.
pad_token_id
,
)
# Override the decoding parameters of Seq2SeqTrainer
training_args_dict
=
training_args
.
to_dict
()
training_args_dict
.
update
(
dict
(
generation_max_length
=
training_args
.
generation_max_length
or
data_args
.
cutoff_len
,
generation_num_beams
=
data_args
.
eval_num_beams
or
training_args
.
generation_num_beams
,
)
)
training_args
=
Seq2SeqTrainingArguments
(
**
training_args_dict
)
# Initialize our Trainer
trainer
=
CustomSeq2SeqTrainer
(
model
=
model
,
args
=
training_args
,
tokenizer
=
tokenizer
,
data_collator
=
data_collator
,
callbacks
=
callbacks
,
compute_metrics
=
ComputeMetrics
(
tokenizer
)
if
training_args
.
predict_with_generate
else
None
,
**
split_dataset
(
dataset
,
data_args
,
training_args
),
)
# Keyword arguments for `model.generate`
gen_kwargs
=
generating_args
.
to_dict
()
gen_kwargs
[
"eos_token_id"
]
=
[
tokenizer
.
eos_token_id
]
+
tokenizer
.
additional_special_tokens_ids
gen_kwargs
[
"pad_token_id"
]
=
tokenizer
.
pad_token_id
gen_kwargs
[
"logits_processor"
]
=
get_logits_processor
()
# Training
if
training_args
.
do_train
:
train_result
=
trainer
.
train
(
resume_from_checkpoint
=
training_args
.
resume_from_checkpoint
)
trainer
.
save_model
()
trainer
.
log_metrics
(
"train"
,
train_result
.
metrics
)
trainer
.
save_metrics
(
"train"
,
train_result
.
metrics
)
trainer
.
save_state
()
if
trainer
.
is_world_process_zero
()
and
finetuning_args
.
plot_loss
:
plot_loss
(
training_args
.
output_dir
,
keys
=
[
"loss"
,
"eval_loss"
])
# Evaluation
if
training_args
.
do_eval
:
metrics
=
trainer
.
evaluate
(
metric_key_prefix
=
"eval"
,
**
gen_kwargs
)
if
training_args
.
predict_with_generate
:
# eval_loss will be wrong if predict_with_generate is enabled
metrics
.
pop
(
"eval_loss"
,
None
)
trainer
.
log_metrics
(
"eval"
,
metrics
)
trainer
.
save_metrics
(
"eval"
,
metrics
)
# Predict
if
training_args
.
do_predict
:
predict_results
=
trainer
.
predict
(
dataset
,
metric_key_prefix
=
"predict"
,
**
gen_kwargs
)
if
training_args
.
predict_with_generate
:
# predict_loss will be wrong if predict_with_generate is enabled
predict_results
.
metrics
.
pop
(
"predict_loss"
,
None
)
trainer
.
log_metrics
(
"predict"
,
predict_results
.
metrics
)
trainer
.
save_metrics
(
"predict"
,
predict_results
.
metrics
)
trainer
.
save_predictions
(
predict_results
)
# Create model card
create_modelcard_and_push
(
trainer
,
model_args
,
data_args
,
training_args
,
finetuning_args
)
LLaMA-Factory/src/llmtuner/train/tuner.py
0 → 100644
View file @
afe180a6
from
typing
import
TYPE_CHECKING
,
Any
,
Dict
,
List
,
Optional
import
torch
from
transformers
import
PreTrainedModel
from
..extras.callbacks
import
LogCallback
from
..extras.logging
import
get_logger
from
..hparams
import
get_infer_args
,
get_train_args
from
..model
import
load_model_and_tokenizer
from
.dpo
import
run_dpo
from
.ppo
import
run_ppo
from
.pt
import
run_pt
from
.rm
import
run_rm
from
.sft
import
run_sft
if
TYPE_CHECKING
:
from
transformers
import
TrainerCallback
logger
=
get_logger
(
__name__
)
def
run_exp
(
args
:
Optional
[
Dict
[
str
,
Any
]]
=
None
,
callbacks
:
Optional
[
List
[
"TrainerCallback"
]]
=
None
):
model_args
,
data_args
,
training_args
,
finetuning_args
,
generating_args
=
get_train_args
(
args
)
callbacks
=
[
LogCallback
()]
if
callbacks
is
None
else
callbacks
if
finetuning_args
.
stage
==
"pt"
:
run_pt
(
model_args
,
data_args
,
training_args
,
finetuning_args
,
callbacks
)
elif
finetuning_args
.
stage
==
"sft"
:
run_sft
(
model_args
,
data_args
,
training_args
,
finetuning_args
,
generating_args
,
callbacks
)
elif
finetuning_args
.
stage
==
"rm"
:
run_rm
(
model_args
,
data_args
,
training_args
,
finetuning_args
,
callbacks
)
elif
finetuning_args
.
stage
==
"ppo"
:
run_ppo
(
model_args
,
data_args
,
training_args
,
finetuning_args
,
generating_args
,
callbacks
)
elif
finetuning_args
.
stage
==
"dpo"
:
run_dpo
(
model_args
,
data_args
,
training_args
,
finetuning_args
,
callbacks
)
else
:
raise
ValueError
(
"Unknown task."
)
def
export_model
(
args
:
Optional
[
Dict
[
str
,
Any
]]
=
None
):
model_args
,
_
,
finetuning_args
,
_
=
get_infer_args
(
args
)
if
model_args
.
export_dir
is
None
:
raise
ValueError
(
"Please specify `export_dir`."
)
if
model_args
.
adapter_name_or_path
is
not
None
and
model_args
.
export_quantization_bit
is
not
None
:
raise
ValueError
(
"Please merge adapters before quantizing the model."
)
model
,
tokenizer
=
load_model_and_tokenizer
(
model_args
,
finetuning_args
)
if
getattr
(
model
,
"quantization_method"
,
None
)
and
model_args
.
adapter_name_or_path
is
not
None
:
raise
ValueError
(
"Cannot merge adapters to a quantized model."
)
if
not
isinstance
(
model
,
PreTrainedModel
):
raise
ValueError
(
"The model is not a `PreTrainedModel`, export aborted."
)
if
getattr
(
model
,
"quantization_method"
,
None
):
model
=
model
.
to
(
"cpu"
)
elif
hasattr
(
model
.
config
,
"torch_dtype"
):
model
=
model
.
to
(
getattr
(
model
.
config
,
"torch_dtype"
)).
to
(
"cpu"
)
else
:
model
=
model
.
to
(
torch
.
float16
).
to
(
"cpu"
)
setattr
(
model
.
config
,
"torch_dtype"
,
torch
.
float16
)
model
.
save_pretrained
(
save_directory
=
model_args
.
export_dir
,
max_shard_size
=
"{}GB"
.
format
(
model_args
.
export_size
),
safe_serialization
=
(
not
model_args
.
export_legacy_format
),
)
if
model_args
.
export_hub_model_id
is
not
None
:
model
.
push_to_hub
(
model_args
.
export_hub_model_id
,
token
=
model_args
.
hf_hub_token
,
max_shard_size
=
"{}GB"
.
format
(
model_args
.
export_size
),
safe_serialization
=
(
not
model_args
.
export_legacy_format
),
)
try
:
tokenizer
.
padding_side
=
"left"
# restore padding side
tokenizer
.
init_kwargs
[
"padding_side"
]
=
"left"
tokenizer
.
save_pretrained
(
model_args
.
export_dir
)
if
model_args
.
export_hub_model_id
is
not
None
:
tokenizer
.
push_to_hub
(
model_args
.
export_hub_model_id
,
token
=
model_args
.
hf_hub_token
)
except
Exception
:
logger
.
warning
(
"Cannot save tokenizer, please copy the files manually."
)
if
__name__
==
"__main__"
:
run_exp
()
LLaMA-Factory/src/llmtuner/train/utils.py
0 → 100644
View file @
afe180a6
from
typing
import
TYPE_CHECKING
,
Optional
,
Union
import
torch
from
..extras.logging
import
get_logger
from
..hparams
import
FinetuningArguments
,
ModelArguments
from
..model
import
load_model_and_tokenizer
,
load_valuehead_params
if
TYPE_CHECKING
:
from
transformers
import
Seq2SeqTrainingArguments
,
Trainer
from
transformers.modeling_utils
import
PreTrainedModel
from
trl
import
AutoModelForCausalLMWithValueHead
from
..hparams
import
DataArguments
logger
=
get_logger
(
__name__
)
def
create_modelcard_and_push
(
trainer
:
"Trainer"
,
model_args
:
"ModelArguments"
,
data_args
:
"DataArguments"
,
training_args
:
"Seq2SeqTrainingArguments"
,
finetuning_args
:
"FinetuningArguments"
,
)
->
None
:
kwargs
=
{
"tasks"
:
"text-generation"
,
"finetuned_from"
:
model_args
.
model_name_or_path
,
"dataset"
:
[
dataset
.
strip
()
for
dataset
in
data_args
.
dataset
.
split
(
","
)],
"tags"
:
[
"llama-factory"
,
finetuning_args
.
finetuning_type
],
}
if
not
training_args
.
do_train
:
pass
elif
training_args
.
push_to_hub
:
trainer
.
push_to_hub
(
**
kwargs
)
else
:
trainer
.
create_model_card
(
license
=
"other"
,
**
kwargs
)
# prevent from connecting to hub
def
create_ref_model
(
model_args
:
"ModelArguments"
,
finetuning_args
:
"FinetuningArguments"
,
add_valuehead
:
Optional
[
bool
]
=
False
)
->
Union
[
"PreTrainedModel"
,
"AutoModelForCausalLMWithValueHead"
]:
r
"""
Creates reference model for PPO/DPO training. Evaluation mode is not supported.
The valuehead parameter is randomly initialized since it is useless for PPO training.
"""
if
finetuning_args
.
ref_model
is
not
None
:
ref_model_args_dict
=
model_args
.
to_dict
()
ref_model_args_dict
.
update
(
dict
(
model_name_or_path
=
finetuning_args
.
ref_model
,
adapter_name_or_path
=
finetuning_args
.
ref_model_adapters
,
quantization_bit
=
finetuning_args
.
ref_model_quantization_bit
,
)
)
ref_model_args
=
ModelArguments
(
**
ref_model_args_dict
)
ref_finetuning_args
=
FinetuningArguments
(
finetuning_type
=
"lora"
)
ref_model
,
_
=
load_model_and_tokenizer
(
ref_model_args
,
ref_finetuning_args
,
is_trainable
=
False
,
add_valuehead
=
add_valuehead
)
logger
.
info
(
"Created reference model from {}"
.
format
(
finetuning_args
.
ref_model
))
else
:
if
finetuning_args
.
finetuning_type
==
"lora"
:
ref_model
=
None
else
:
ref_model
,
_
=
load_model_and_tokenizer
(
model_args
,
finetuning_args
,
is_trainable
=
False
,
add_valuehead
=
add_valuehead
)
logger
.
info
(
"Created reference model from the model itself."
)
return
ref_model
def
create_reward_model
(
model
:
"AutoModelForCausalLMWithValueHead"
,
model_args
:
"ModelArguments"
,
finetuning_args
:
"FinetuningArguments"
)
->
"AutoModelForCausalLMWithValueHead"
:
r
"""
Creates reward model for PPO training.
"""
if
finetuning_args
.
reward_model_type
==
"api"
:
assert
finetuning_args
.
reward_model
.
startswith
(
"http"
),
"Please provide full url."
logger
.
info
(
"Use reward server {}"
.
format
(
finetuning_args
.
reward_model
))
return
finetuning_args
.
reward_model
elif
finetuning_args
.
reward_model_type
==
"lora"
:
model
.
pretrained_model
.
load_adapter
(
finetuning_args
.
reward_model
,
"reward"
)
for
name
,
param
in
model
.
named_parameters
():
# https://github.com/huggingface/peft/issues/1090
if
"default"
in
name
:
param
.
data
=
param
.
data
.
to
(
torch
.
float32
)
# trainable params should in fp32
vhead_params
=
load_valuehead_params
(
finetuning_args
.
reward_model
,
model_args
)
assert
vhead_params
is
not
None
,
"Reward model is not correctly loaded."
model
.
register_buffer
(
"reward_head_weight"
,
vhead_params
[
"v_head.summary.weight"
],
persistent
=
False
)
model
.
register_buffer
(
"reward_head_bias"
,
vhead_params
[
"v_head.summary.bias"
],
persistent
=
False
)
model
.
register_buffer
(
"default_head_weight"
,
torch
.
zeros_like
(
vhead_params
[
"v_head.summary.weight"
]),
persistent
=
False
)
model
.
register_buffer
(
"default_head_bias"
,
torch
.
zeros_like
(
vhead_params
[
"v_head.summary.bias"
]),
persistent
=
False
)
logger
.
info
(
"Loaded adapter weights of reward model from {}"
.
format
(
finetuning_args
.
reward_model
))
return
None
else
:
reward_model_args_dict
=
model_args
.
to_dict
()
reward_model_args_dict
.
update
(
dict
(
model_name_or_path
=
finetuning_args
.
reward_model
,
adapter_name_or_path
=
finetuning_args
.
reward_model_adapters
,
quantization_bit
=
finetuning_args
.
reward_model_quantization_bit
,
)
)
reward_model_args
=
ModelArguments
(
**
reward_model_args_dict
)
reward_finetuning_args
=
FinetuningArguments
(
finetuning_type
=
"lora"
)
reward_model
,
_
=
load_model_and_tokenizer
(
reward_model_args
,
reward_finetuning_args
,
is_trainable
=
False
,
add_valuehead
=
True
)
logger
.
info
(
"Loaded full weights of reward model from {}"
.
format
(
finetuning_args
.
reward_model
))
logger
.
warning
(
"Please ensure the ppo model and reward model share SAME tokenizer and vocabulary."
)
return
reward_model
LLaMA-Factory/src/llmtuner/webui/__init__.py
0 → 100644
View file @
afe180a6
from
.interface
import
create_ui
,
create_web_demo
__all__
=
[
"create_ui"
,
"create_web_demo"
]
LLaMA-Factory/src/llmtuner/webui/chatter.py
0 → 100644
View file @
afe180a6
import
json
from
typing
import
TYPE_CHECKING
,
Any
,
Dict
,
Generator
,
List
,
Optional
,
Sequence
,
Tuple
import
gradio
as
gr
from
gradio.components
import
Component
# cannot use TYPE_CHECKING here
from
..chat
import
ChatModel
from
..data
import
Role
from
..extras.misc
import
torch_gc
from
..hparams
import
GeneratingArguments
from
.common
import
get_save_dir
from
.locales
import
ALERTS
if
TYPE_CHECKING
:
from
.manager
import
Manager
class
WebChatModel
(
ChatModel
):
def
__init__
(
self
,
manager
:
"Manager"
,
demo_mode
:
Optional
[
bool
]
=
False
,
lazy_init
:
Optional
[
bool
]
=
True
)
->
None
:
self
.
manager
=
manager
self
.
demo_mode
=
demo_mode
self
.
model
=
None
self
.
tokenizer
=
None
self
.
generating_args
=
GeneratingArguments
()
if
not
lazy_init
:
# read arguments from command line
super
().
__init__
()
if
demo_mode
:
# load demo_config.json if exists
import
json
try
:
with
open
(
"demo_config.json"
,
"r"
,
encoding
=
"utf-8"
)
as
f
:
args
=
json
.
load
(
f
)
assert
args
.
get
(
"model_name_or_path"
,
None
)
and
args
.
get
(
"template"
,
None
)
super
().
__init__
(
args
)
except
AssertionError
:
print
(
"Please provided model name and template in `demo_config.json`."
)
except
Exception
:
print
(
"Cannot find `demo_config.json` at current directory."
)
@
property
def
loaded
(
self
)
->
bool
:
return
self
.
model
is
not
None
def
load_model
(
self
,
data
:
Dict
[
Component
,
Any
])
->
Generator
[
str
,
None
,
None
]:
get
=
lambda
name
:
data
[
self
.
manager
.
get_elem_by_name
(
name
)]
lang
=
get
(
"top.lang"
)
error
=
""
if
self
.
loaded
:
error
=
ALERTS
[
"err_exists"
][
lang
]
elif
not
get
(
"top.model_name"
):
error
=
ALERTS
[
"err_no_model"
][
lang
]
elif
not
get
(
"top.model_path"
):
error
=
ALERTS
[
"err_no_path"
][
lang
]
elif
self
.
demo_mode
:
error
=
ALERTS
[
"err_demo"
][
lang
]
if
error
:
gr
.
Warning
(
error
)
yield
error
return
if
get
(
"top.adapter_path"
):
adapter_name_or_path
=
","
.
join
(
[
get_save_dir
(
get
(
"top.model_name"
),
get
(
"top.finetuning_type"
),
adapter
)
for
adapter
in
get
(
"top.adapter_path"
)
]
)
else
:
adapter_name_or_path
=
None
yield
ALERTS
[
"info_loading"
][
lang
]
args
=
dict
(
model_name_or_path
=
get
(
"top.model_path"
),
adapter_name_or_path
=
adapter_name_or_path
,
finetuning_type
=
get
(
"top.finetuning_type"
),
quantization_bit
=
int
(
get
(
"top.quantization_bit"
))
if
get
(
"top.quantization_bit"
)
in
[
"8"
,
"4"
]
else
None
,
template
=
get
(
"top.template"
),
flash_attn
=
(
get
(
"top.booster"
)
==
"flash_attn"
),
use_unsloth
=
(
get
(
"top.booster"
)
==
"unsloth"
),
rope_scaling
=
get
(
"top.rope_scaling"
)
if
get
(
"top.rope_scaling"
)
in
[
"linear"
,
"dynamic"
]
else
None
,
)
super
().
__init__
(
args
)
yield
ALERTS
[
"info_loaded"
][
lang
]
def
unload_model
(
self
,
data
:
Dict
[
Component
,
Any
])
->
Generator
[
str
,
None
,
None
]:
lang
=
data
[
self
.
manager
.
get_elem_by_name
(
"top.lang"
)]
if
self
.
demo_mode
:
gr
.
Warning
(
ALERTS
[
"err_demo"
][
lang
])
yield
ALERTS
[
"err_demo"
][
lang
]
return
yield
ALERTS
[
"info_unloading"
][
lang
]
self
.
model
=
None
self
.
tokenizer
=
None
torch_gc
()
yield
ALERTS
[
"info_unloaded"
][
lang
]
def
predict
(
self
,
chatbot
:
List
[
Tuple
[
str
,
str
]],
query
:
str
,
messages
:
Sequence
[
Tuple
[
str
,
str
]],
system
:
str
,
tools
:
str
,
max_new_tokens
:
int
,
top_p
:
float
,
temperature
:
float
,
)
->
Generator
[
Tuple
[
Sequence
[
Tuple
[
str
,
str
]],
Sequence
[
Tuple
[
str
,
str
]]],
None
,
None
]:
chatbot
.
append
([
query
,
""
])
query_messages
=
messages
+
[{
"role"
:
Role
.
USER
,
"content"
:
query
}]
response
=
""
for
new_text
in
self
.
stream_chat
(
query_messages
,
system
,
tools
,
max_new_tokens
=
max_new_tokens
,
top_p
=
top_p
,
temperature
=
temperature
):
response
+=
new_text
if
tools
:
result
=
self
.
template
.
format_tools
.
extract
(
response
)
else
:
result
=
response
if
isinstance
(
result
,
tuple
):
name
,
arguments
=
result
arguments
=
json
.
loads
(
arguments
)
tool_call
=
json
.
dumps
({
"name"
:
name
,
"arguments"
:
arguments
},
ensure_ascii
=
False
)
output_messages
=
query_messages
+
[{
"role"
:
Role
.
FUNCTION
,
"content"
:
tool_call
}]
bot_text
=
"```json
\n
"
+
tool_call
+
"
\n
```"
else
:
output_messages
=
query_messages
+
[{
"role"
:
Role
.
ASSISTANT
,
"content"
:
result
}]
bot_text
=
result
chatbot
[
-
1
]
=
[
query
,
self
.
postprocess
(
bot_text
)]
yield
chatbot
,
output_messages
def
postprocess
(
self
,
response
:
str
)
->
str
:
blocks
=
response
.
split
(
"```"
)
for
i
,
block
in
enumerate
(
blocks
):
if
i
%
2
==
0
:
blocks
[
i
]
=
block
.
replace
(
"<"
,
"<"
).
replace
(
">"
,
">"
)
return
"```"
.
join
(
blocks
)
LLaMA-Factory/src/llmtuner/webui/common.py
0 → 100644
View file @
afe180a6
import
json
import
os
from
collections
import
defaultdict
from
typing
import
Any
,
Dict
,
Optional
import
gradio
as
gr
from
peft.utils
import
SAFETENSORS_WEIGHTS_NAME
,
WEIGHTS_NAME
from
..extras.constants
import
(
DATA_CONFIG
,
DEFAULT_MODULE
,
DEFAULT_TEMPLATE
,
PEFT_METHODS
,
SUPPORTED_MODELS
,
TRAINING_STAGES
,
DownloadSource
,
)
from
..extras.misc
import
use_modelscope
ADAPTER_NAMES
=
{
WEIGHTS_NAME
,
SAFETENSORS_WEIGHTS_NAME
}
DEFAULT_CACHE_DIR
=
"cache"
DEFAULT_DATA_DIR
=
"data"
DEFAULT_SAVE_DIR
=
"saves"
USER_CONFIG
=
"user.config"
def
get_save_dir
(
*
args
)
->
os
.
PathLike
:
return
os
.
path
.
join
(
DEFAULT_SAVE_DIR
,
*
args
)
def
get_config_path
()
->
os
.
PathLike
:
return
os
.
path
.
join
(
DEFAULT_CACHE_DIR
,
USER_CONFIG
)
def
load_config
()
->
Dict
[
str
,
Any
]:
try
:
with
open
(
get_config_path
(),
"r"
,
encoding
=
"utf-8"
)
as
f
:
return
json
.
load
(
f
)
except
Exception
:
return
{
"lang"
:
None
,
"last_model"
:
None
,
"path_dict"
:
{},
"cache_dir"
:
None
}
def
save_config
(
lang
:
str
,
model_name
:
Optional
[
str
]
=
None
,
model_path
:
Optional
[
str
]
=
None
)
->
None
:
os
.
makedirs
(
DEFAULT_CACHE_DIR
,
exist_ok
=
True
)
user_config
=
load_config
()
user_config
[
"lang"
]
=
lang
or
user_config
[
"lang"
]
if
model_name
:
user_config
[
"last_model"
]
=
model_name
user_config
[
"path_dict"
][
model_name
]
=
model_path
with
open
(
get_config_path
(),
"w"
,
encoding
=
"utf-8"
)
as
f
:
json
.
dump
(
user_config
,
f
,
indent
=
2
,
ensure_ascii
=
False
)
def
get_model_path
(
model_name
:
str
)
->
str
:
user_config
=
load_config
()
path_dict
:
Dict
[
DownloadSource
,
str
]
=
SUPPORTED_MODELS
.
get
(
model_name
,
defaultdict
(
str
))
model_path
=
user_config
[
"path_dict"
].
get
(
model_name
,
None
)
or
path_dict
.
get
(
DownloadSource
.
DEFAULT
,
None
)
if
(
use_modelscope
()
and
path_dict
.
get
(
DownloadSource
.
MODELSCOPE
)
and
model_path
==
path_dict
.
get
(
DownloadSource
.
DEFAULT
)
):
# replace path
model_path
=
path_dict
.
get
(
DownloadSource
.
MODELSCOPE
)
return
model_path
def
get_prefix
(
model_name
:
str
)
->
str
:
return
model_name
.
split
(
"-"
)[
0
]
def
get_module
(
model_name
:
str
)
->
str
:
return
DEFAULT_MODULE
.
get
(
get_prefix
(
model_name
),
"q_proj,v_proj"
)
def
get_template
(
model_name
:
str
)
->
str
:
if
model_name
and
model_name
.
endswith
(
"Chat"
)
and
get_prefix
(
model_name
)
in
DEFAULT_TEMPLATE
:
return
DEFAULT_TEMPLATE
[
get_prefix
(
model_name
)]
return
"default"
def
list_adapters
(
model_name
:
str
,
finetuning_type
:
str
)
->
Dict
[
str
,
Any
]:
if
finetuning_type
not
in
PEFT_METHODS
:
return
gr
.
update
(
value
=
[],
choices
=
[],
interactive
=
False
)
adapters
=
[]
if
model_name
and
finetuning_type
==
"lora"
:
save_dir
=
get_save_dir
(
model_name
,
finetuning_type
)
if
save_dir
and
os
.
path
.
isdir
(
save_dir
):
for
adapter
in
os
.
listdir
(
save_dir
):
if
os
.
path
.
isdir
(
os
.
path
.
join
(
save_dir
,
adapter
))
and
any
(
os
.
path
.
isfile
(
os
.
path
.
join
(
save_dir
,
adapter
,
name
))
for
name
in
ADAPTER_NAMES
):
adapters
.
append
(
adapter
)
return
gr
.
update
(
value
=
[],
choices
=
adapters
,
interactive
=
True
)
def
load_dataset_info
(
dataset_dir
:
str
)
->
Dict
[
str
,
Dict
[
str
,
Any
]]:
try
:
with
open
(
os
.
path
.
join
(
dataset_dir
,
DATA_CONFIG
),
"r"
,
encoding
=
"utf-8"
)
as
f
:
return
json
.
load
(
f
)
except
Exception
as
err
:
print
(
"Cannot open {} due to {}."
.
format
(
os
.
path
.
join
(
dataset_dir
,
DATA_CONFIG
),
str
(
err
)))
return
{}
def
list_dataset
(
dataset_dir
:
Optional
[
str
]
=
None
,
training_stage
:
Optional
[
str
]
=
list
(
TRAINING_STAGES
.
keys
())[
0
]
)
->
Dict
[
str
,
Any
]:
dataset_info
=
load_dataset_info
(
dataset_dir
if
dataset_dir
is
not
None
else
DEFAULT_DATA_DIR
)
ranking
=
TRAINING_STAGES
[
training_stage
]
in
[
"rm"
,
"dpo"
]
datasets
=
[
k
for
k
,
v
in
dataset_info
.
items
()
if
v
.
get
(
"ranking"
,
False
)
==
ranking
]
return
gr
.
update
(
value
=
[],
choices
=
datasets
)
LLaMA-Factory/src/llmtuner/webui/components/__init__.py
0 → 100644
View file @
afe180a6
from
.chatbot
import
create_chat_box
from
.eval
import
create_eval_tab
from
.export
import
create_export_tab
from
.infer
import
create_infer_tab
from
.top
import
create_top
from
.train
import
create_train_tab
__all__
=
[
"create_chat_box"
,
"create_eval_tab"
,
"create_export_tab"
,
"create_infer_tab"
,
"create_top"
,
"create_train_tab"
,
]
LLaMA-Factory/src/llmtuner/webui/components/chatbot.py
0 → 100644
View file @
afe180a6
from
typing
import
TYPE_CHECKING
,
Dict
,
Optional
,
Tuple
import
gradio
as
gr
from
..utils
import
check_json_schema
if
TYPE_CHECKING
:
from
gradio.blocks
import
Block
from
gradio.components
import
Component
from
..engine
import
Engine
def
create_chat_box
(
engine
:
"Engine"
,
visible
:
Optional
[
bool
]
=
False
)
->
Tuple
[
"Block"
,
"Component"
,
"Component"
,
Dict
[
str
,
"Component"
]]:
with
gr
.
Box
(
visible
=
visible
)
as
chat_box
:
chatbot
=
gr
.
Chatbot
()
messages
=
gr
.
State
([])
with
gr
.
Row
():
with
gr
.
Column
(
scale
=
4
):
system
=
gr
.
Textbox
(
show_label
=
False
)
tools
=
gr
.
Textbox
(
show_label
=
False
,
lines
=
2
)
query
=
gr
.
Textbox
(
show_label
=
False
,
lines
=
8
)
submit_btn
=
gr
.
Button
(
variant
=
"primary"
)
with
gr
.
Column
(
scale
=
1
):
clear_btn
=
gr
.
Button
()
gen_kwargs
=
engine
.
chatter
.
generating_args
max_new_tokens
=
gr
.
Slider
(
10
,
2048
,
value
=
gen_kwargs
.
max_new_tokens
,
step
=
1
)
top_p
=
gr
.
Slider
(
0.01
,
1
,
value
=
gen_kwargs
.
top_p
,
step
=
0.01
)
temperature
=
gr
.
Slider
(
0.01
,
1.5
,
value
=
gen_kwargs
.
temperature
,
step
=
0.01
)
tools
.
input
(
check_json_schema
,
[
tools
,
engine
.
manager
.
get_elem_by_name
(
"top.lang"
)])
submit_btn
.
click
(
engine
.
chatter
.
predict
,
[
chatbot
,
query
,
messages
,
system
,
tools
,
max_new_tokens
,
top_p
,
temperature
],
[
chatbot
,
messages
],
show_progress
=
True
,
).
then
(
lambda
:
gr
.
update
(
value
=
""
),
outputs
=
[
query
])
clear_btn
.
click
(
lambda
:
([],
[]),
outputs
=
[
chatbot
,
messages
],
show_progress
=
True
)
return
(
chat_box
,
chatbot
,
messages
,
dict
(
system
=
system
,
tools
=
tools
,
query
=
query
,
submit_btn
=
submit_btn
,
clear_btn
=
clear_btn
,
max_new_tokens
=
max_new_tokens
,
top_p
=
top_p
,
temperature
=
temperature
,
),
)
LLaMA-Factory/src/llmtuner/webui/components/data.py
0 → 100644
View file @
afe180a6
import
json
import
os
from
typing
import
TYPE_CHECKING
,
Any
,
Dict
,
Tuple
import
gradio
as
gr
from
...extras.constants
import
DATA_CONFIG
if
TYPE_CHECKING
:
from
gradio.components
import
Component
PAGE_SIZE
=
2
def
prev_page
(
page_index
:
int
)
->
int
:
return
page_index
-
1
if
page_index
>
0
else
page_index
def
next_page
(
page_index
:
int
,
total_num
:
int
)
->
int
:
return
page_index
+
1
if
(
page_index
+
1
)
*
PAGE_SIZE
<
total_num
else
page_index
def
can_preview
(
dataset_dir
:
str
,
dataset
:
list
)
->
Dict
[
str
,
Any
]:
try
:
with
open
(
os
.
path
.
join
(
dataset_dir
,
DATA_CONFIG
),
"r"
,
encoding
=
"utf-8"
)
as
f
:
dataset_info
=
json
.
load
(
f
)
except
Exception
:
return
gr
.
update
(
interactive
=
False
)
if
(
len
(
dataset
)
>
0
and
"file_name"
in
dataset_info
[
dataset
[
0
]]
and
os
.
path
.
isfile
(
os
.
path
.
join
(
dataset_dir
,
dataset_info
[
dataset
[
0
]][
"file_name"
]))
):
return
gr
.
update
(
interactive
=
True
)
else
:
return
gr
.
update
(
interactive
=
False
)
def
get_preview
(
dataset_dir
:
str
,
dataset
:
list
,
page_index
:
int
)
->
Tuple
[
int
,
list
,
Dict
[
str
,
Any
]]:
with
open
(
os
.
path
.
join
(
dataset_dir
,
DATA_CONFIG
),
"r"
,
encoding
=
"utf-8"
)
as
f
:
dataset_info
=
json
.
load
(
f
)
data_file
:
str
=
dataset_info
[
dataset
[
0
]][
"file_name"
]
with
open
(
os
.
path
.
join
(
dataset_dir
,
data_file
),
"r"
,
encoding
=
"utf-8"
)
as
f
:
if
data_file
.
endswith
(
".json"
):
data
=
json
.
load
(
f
)
elif
data_file
.
endswith
(
".jsonl"
):
data
=
[
json
.
loads
(
line
)
for
line
in
f
]
else
:
data
=
[
line
for
line
in
f
]
# noqa: C416
return
len
(
data
),
data
[
PAGE_SIZE
*
page_index
:
PAGE_SIZE
*
(
page_index
+
1
)],
gr
.
update
(
visible
=
True
)
def
create_preview_box
(
dataset_dir
:
"gr.Textbox"
,
dataset
:
"gr.Dropdown"
)
->
Dict
[
str
,
"Component"
]:
data_preview_btn
=
gr
.
Button
(
interactive
=
False
,
scale
=
1
)
with
gr
.
Column
(
visible
=
False
,
elem_classes
=
"modal-box"
)
as
preview_box
:
with
gr
.
Row
():
preview_count
=
gr
.
Number
(
value
=
0
,
interactive
=
False
,
precision
=
0
)
page_index
=
gr
.
Number
(
value
=
0
,
interactive
=
False
,
precision
=
0
)
with
gr
.
Row
():
prev_btn
=
gr
.
Button
()
next_btn
=
gr
.
Button
()
close_btn
=
gr
.
Button
()
with
gr
.
Row
():
preview_samples
=
gr
.
JSON
(
interactive
=
False
)
dataset
.
change
(
can_preview
,
[
dataset_dir
,
dataset
],
[
data_preview_btn
],
queue
=
False
).
then
(
lambda
:
0
,
outputs
=
[
page_index
],
queue
=
False
)
data_preview_btn
.
click
(
get_preview
,
[
dataset_dir
,
dataset
,
page_index
],
[
preview_count
,
preview_samples
,
preview_box
],
queue
=
False
)
prev_btn
.
click
(
prev_page
,
[
page_index
],
[
page_index
],
queue
=
False
).
then
(
get_preview
,
[
dataset_dir
,
dataset
,
page_index
],
[
preview_count
,
preview_samples
,
preview_box
],
queue
=
False
)
next_btn
.
click
(
next_page
,
[
page_index
,
preview_count
],
[
page_index
],
queue
=
False
).
then
(
get_preview
,
[
dataset_dir
,
dataset
,
page_index
],
[
preview_count
,
preview_samples
,
preview_box
],
queue
=
False
)
close_btn
.
click
(
lambda
:
gr
.
update
(
visible
=
False
),
outputs
=
[
preview_box
],
queue
=
False
)
return
dict
(
data_preview_btn
=
data_preview_btn
,
preview_count
=
preview_count
,
page_index
=
page_index
,
prev_btn
=
prev_btn
,
next_btn
=
next_btn
,
close_btn
=
close_btn
,
preview_samples
=
preview_samples
,
)
LLaMA-Factory/src/llmtuner/webui/components/eval.py
0 → 100644
View file @
afe180a6
from
typing
import
TYPE_CHECKING
,
Dict
import
gradio
as
gr
from
..common
import
DEFAULT_DATA_DIR
,
list_dataset
from
.data
import
create_preview_box
if
TYPE_CHECKING
:
from
gradio.components
import
Component
from
..engine
import
Engine
def
create_eval_tab
(
engine
:
"Engine"
)
->
Dict
[
str
,
"Component"
]:
input_elems
=
engine
.
manager
.
get_base_elems
()
elem_dict
=
dict
()
with
gr
.
Row
():
dataset_dir
=
gr
.
Textbox
(
value
=
DEFAULT_DATA_DIR
,
scale
=
2
)
dataset
=
gr
.
Dropdown
(
multiselect
=
True
,
scale
=
4
)
preview_elems
=
create_preview_box
(
dataset_dir
,
dataset
)
dataset_dir
.
change
(
list_dataset
,
[
dataset_dir
],
[
dataset
],
queue
=
False
)
input_elems
.
update
({
dataset_dir
,
dataset
})
elem_dict
.
update
(
dict
(
dataset_dir
=
dataset_dir
,
dataset
=
dataset
,
**
preview_elems
))
with
gr
.
Row
():
cutoff_len
=
gr
.
Slider
(
value
=
1024
,
minimum
=
4
,
maximum
=
8192
,
step
=
1
)
max_samples
=
gr
.
Textbox
(
value
=
"100000"
)
batch_size
=
gr
.
Slider
(
value
=
8
,
minimum
=
1
,
maximum
=
512
,
step
=
1
)
predict
=
gr
.
Checkbox
(
value
=
True
)
input_elems
.
update
({
cutoff_len
,
max_samples
,
batch_size
,
predict
})
elem_dict
.
update
(
dict
(
cutoff_len
=
cutoff_len
,
max_samples
=
max_samples
,
batch_size
=
batch_size
,
predict
=
predict
))
with
gr
.
Row
():
max_new_tokens
=
gr
.
Slider
(
10
,
2048
,
value
=
128
,
step
=
1
)
top_p
=
gr
.
Slider
(
0.01
,
1
,
value
=
0.7
,
step
=
0.01
)
temperature
=
gr
.
Slider
(
0.01
,
1.5
,
value
=
0.95
,
step
=
0.01
)
output_dir
=
gr
.
Textbox
()
input_elems
.
update
({
max_new_tokens
,
top_p
,
temperature
,
output_dir
})
elem_dict
.
update
(
dict
(
max_new_tokens
=
max_new_tokens
,
top_p
=
top_p
,
temperature
=
temperature
,
output_dir
=
output_dir
))
with
gr
.
Row
():
cmd_preview_btn
=
gr
.
Button
()
start_btn
=
gr
.
Button
()
stop_btn
=
gr
.
Button
()
with
gr
.
Row
():
resume_btn
=
gr
.
Checkbox
(
visible
=
False
,
interactive
=
False
,
value
=
False
)
process_bar
=
gr
.
Slider
(
visible
=
False
,
interactive
=
False
)
with
gr
.
Box
():
output_box
=
gr
.
Markdown
()
output_elems
=
[
output_box
,
process_bar
]
elem_dict
.
update
(
dict
(
cmd_preview_btn
=
cmd_preview_btn
,
start_btn
=
start_btn
,
stop_btn
=
stop_btn
,
resume_btn
=
resume_btn
,
process_bar
=
process_bar
,
output_box
=
output_box
,
)
)
cmd_preview_btn
.
click
(
engine
.
runner
.
preview_eval
,
input_elems
,
output_elems
)
start_btn
.
click
(
engine
.
runner
.
run_eval
,
input_elems
,
output_elems
)
stop_btn
.
click
(
engine
.
runner
.
set_abort
,
queue
=
False
)
resume_btn
.
change
(
engine
.
runner
.
monitor
,
outputs
=
output_elems
)
return
elem_dict
LLaMA-Factory/src/llmtuner/webui/components/export.py
0 → 100644
View file @
afe180a6
from
typing
import
TYPE_CHECKING
,
Dict
,
Generator
,
List
import
gradio
as
gr
from
...train
import
export_model
from
..common
import
get_save_dir
from
..locales
import
ALERTS
if
TYPE_CHECKING
:
from
gradio.components
import
Component
from
..engine
import
Engine
GPTQ_BITS
=
[
"8"
,
"4"
,
"3"
,
"2"
]
def
save_model
(
lang
:
str
,
model_name
:
str
,
model_path
:
str
,
adapter_path
:
List
[
str
],
finetuning_type
:
str
,
template
:
str
,
max_shard_size
:
int
,
export_quantization_bit
:
int
,
export_quantization_dataset
:
str
,
export_dir
:
str
,
)
->
Generator
[
str
,
None
,
None
]:
error
=
""
if
not
model_name
:
error
=
ALERTS
[
"err_no_model"
][
lang
]
elif
not
model_path
:
error
=
ALERTS
[
"err_no_path"
][
lang
]
elif
not
export_dir
:
error
=
ALERTS
[
"err_no_export_dir"
][
lang
]
elif
export_quantization_bit
in
GPTQ_BITS
and
not
export_quantization_dataset
:
error
=
ALERTS
[
"err_no_dataset"
][
lang
]
elif
export_quantization_bit
not
in
GPTQ_BITS
and
not
adapter_path
:
error
=
ALERTS
[
"err_no_adapter"
][
lang
]
if
error
:
gr
.
Warning
(
error
)
yield
error
return
if
adapter_path
:
adapter_name_or_path
=
","
.
join
(
[
get_save_dir
(
model_name
,
finetuning_type
,
adapter
)
for
adapter
in
adapter_path
]
)
else
:
adapter_name_or_path
=
None
args
=
dict
(
model_name_or_path
=
model_path
,
adapter_name_or_path
=
adapter_name_or_path
,
finetuning_type
=
finetuning_type
,
template
=
template
,
export_dir
=
export_dir
,
export_size
=
max_shard_size
,
export_quantization_bit
=
int
(
export_quantization_bit
)
if
export_quantization_bit
in
GPTQ_BITS
else
None
,
export_quantization_dataset
=
export_quantization_dataset
,
)
yield
ALERTS
[
"info_exporting"
][
lang
]
export_model
(
args
)
yield
ALERTS
[
"info_exported"
][
lang
]
def
create_export_tab
(
engine
:
"Engine"
)
->
Dict
[
str
,
"Component"
]:
with
gr
.
Row
():
max_shard_size
=
gr
.
Slider
(
value
=
1
,
minimum
=
1
,
maximum
=
100
)
export_quantization_bit
=
gr
.
Dropdown
(
choices
=
[
"none"
,
"8"
,
"4"
,
"3"
,
"2"
],
value
=
"none"
)
export_quantization_dataset
=
gr
.
Textbox
(
value
=
"data/c4_demo.json"
)
export_dir
=
gr
.
Textbox
()
export_btn
=
gr
.
Button
()
info_box
=
gr
.
Textbox
(
show_label
=
False
,
interactive
=
False
)
export_btn
.
click
(
save_model
,
[
engine
.
manager
.
get_elem_by_name
(
"top.lang"
),
engine
.
manager
.
get_elem_by_name
(
"top.model_name"
),
engine
.
manager
.
get_elem_by_name
(
"top.model_path"
),
engine
.
manager
.
get_elem_by_name
(
"top.adapter_path"
),
engine
.
manager
.
get_elem_by_name
(
"top.finetuning_type"
),
engine
.
manager
.
get_elem_by_name
(
"top.template"
),
max_shard_size
,
export_quantization_bit
,
export_quantization_dataset
,
export_dir
,
],
[
info_box
],
)
return
dict
(
max_shard_size
=
max_shard_size
,
export_quantization_bit
=
export_quantization_bit
,
export_quantization_dataset
=
export_quantization_dataset
,
export_dir
=
export_dir
,
export_btn
=
export_btn
,
info_box
=
info_box
,
)
LLaMA-Factory/src/llmtuner/webui/components/infer.py
0 → 100644
View file @
afe180a6
from
typing
import
TYPE_CHECKING
,
Dict
import
gradio
as
gr
from
.chatbot
import
create_chat_box
if
TYPE_CHECKING
:
from
gradio.components
import
Component
from
..engine
import
Engine
def
create_infer_tab
(
engine
:
"Engine"
)
->
Dict
[
str
,
"Component"
]:
input_elems
=
engine
.
manager
.
get_base_elems
()
elem_dict
=
dict
()
with
gr
.
Row
():
load_btn
=
gr
.
Button
()
unload_btn
=
gr
.
Button
()
info_box
=
gr
.
Textbox
(
show_label
=
False
,
interactive
=
False
)
elem_dict
.
update
(
dict
(
load_btn
=
load_btn
,
unload_btn
=
unload_btn
,
info_box
=
info_box
))
chat_box
,
chatbot
,
history
,
chat_elems
=
create_chat_box
(
engine
,
visible
=
False
)
elem_dict
.
update
(
dict
(
chat_box
=
chat_box
,
**
chat_elems
))
load_btn
.
click
(
engine
.
chatter
.
load_model
,
input_elems
,
[
info_box
]).
then
(
lambda
:
gr
.
update
(
visible
=
engine
.
chatter
.
loaded
),
outputs
=
[
chat_box
]
)
unload_btn
.
click
(
engine
.
chatter
.
unload_model
,
input_elems
,
[
info_box
]).
then
(
lambda
:
([],
[]),
outputs
=
[
chatbot
,
history
]
).
then
(
lambda
:
gr
.
update
(
visible
=
engine
.
chatter
.
loaded
),
outputs
=
[
chat_box
])
return
elem_dict
LLaMA-Factory/src/llmtuner/webui/components/top.py
0 → 100644
View file @
afe180a6
from
typing
import
TYPE_CHECKING
,
Dict
import
gradio
as
gr
from
...data
import
templates
from
...extras.constants
import
METHODS
,
SUPPORTED_MODELS
from
..common
import
get_model_path
,
get_template
,
list_adapters
,
save_config
from
..utils
import
can_quantize
if
TYPE_CHECKING
:
from
gradio.components
import
Component
def
create_top
()
->
Dict
[
str
,
"Component"
]:
available_models
=
list
(
SUPPORTED_MODELS
.
keys
())
+
[
"Custom"
]
with
gr
.
Row
():
lang
=
gr
.
Dropdown
(
choices
=
[
"en"
,
"ru"
,
"zh"
],
scale
=
1
)
model_name
=
gr
.
Dropdown
(
choices
=
available_models
,
scale
=
3
)
model_path
=
gr
.
Textbox
(
scale
=
3
)
with
gr
.
Row
():
finetuning_type
=
gr
.
Dropdown
(
choices
=
METHODS
,
value
=
"lora"
,
scale
=
1
)
adapter_path
=
gr
.
Dropdown
(
multiselect
=
True
,
scale
=
5
,
allow_custom_value
=
True
)
refresh_btn
=
gr
.
Button
(
scale
=
1
)
with
gr
.
Accordion
(
label
=
"Advanced config"
,
open
=
False
)
as
advanced_tab
:
with
gr
.
Row
():
quantization_bit
=
gr
.
Dropdown
(
choices
=
[
"none"
,
"8"
,
"4"
],
value
=
"none"
)
template
=
gr
.
Dropdown
(
choices
=
list
(
templates
.
keys
()),
value
=
"default"
)
rope_scaling
=
gr
.
Radio
(
choices
=
[
"none"
,
"linear"
,
"dynamic"
],
value
=
"none"
)
booster
=
gr
.
Radio
(
choices
=
[
"none"
,
"flash_attn"
,
"unsloth"
],
value
=
"none"
)
model_name
.
change
(
list_adapters
,
[
model_name
,
finetuning_type
],
[
adapter_path
],
queue
=
False
).
then
(
get_model_path
,
[
model_name
],
[
model_path
],
queue
=
False
).
then
(
get_template
,
[
model_name
],
[
template
],
queue
=
False
)
# do not save config since the below line will save
model_path
.
change
(
save_config
,
inputs
=
[
lang
,
model_name
,
model_path
],
queue
=
False
)
finetuning_type
.
change
(
list_adapters
,
[
model_name
,
finetuning_type
],
[
adapter_path
],
queue
=
False
).
then
(
can_quantize
,
[
finetuning_type
],
[
quantization_bit
],
queue
=
False
)
refresh_btn
.
click
(
list_adapters
,
[
model_name
,
finetuning_type
],
[
adapter_path
],
queue
=
False
)
return
dict
(
lang
=
lang
,
model_name
=
model_name
,
model_path
=
model_path
,
finetuning_type
=
finetuning_type
,
adapter_path
=
adapter_path
,
refresh_btn
=
refresh_btn
,
advanced_tab
=
advanced_tab
,
quantization_bit
=
quantization_bit
,
template
=
template
,
rope_scaling
=
rope_scaling
,
booster
=
booster
,
)
LLaMA-Factory/src/llmtuner/webui/components/train.py
0 → 100644
View file @
afe180a6
from
typing
import
TYPE_CHECKING
,
Dict
import
gradio
as
gr
from
transformers.trainer_utils
import
SchedulerType
from
...extras.constants
import
TRAINING_STAGES
from
..common
import
DEFAULT_DATA_DIR
,
list_adapters
,
list_dataset
from
..components.data
import
create_preview_box
from
..utils
import
gen_plot
if
TYPE_CHECKING
:
from
gradio.components
import
Component
from
..engine
import
Engine
def
create_train_tab
(
engine
:
"Engine"
)
->
Dict
[
str
,
"Component"
]:
input_elems
=
engine
.
manager
.
get_base_elems
()
elem_dict
=
dict
()
with
gr
.
Row
():
training_stage
=
gr
.
Dropdown
(
choices
=
list
(
TRAINING_STAGES
.
keys
()),
value
=
list
(
TRAINING_STAGES
.
keys
())[
0
],
scale
=
2
)
dataset_dir
=
gr
.
Textbox
(
value
=
DEFAULT_DATA_DIR
,
scale
=
2
)
dataset
=
gr
.
Dropdown
(
multiselect
=
True
,
scale
=
4
)
preview_elems
=
create_preview_box
(
dataset_dir
,
dataset
)
training_stage
.
change
(
list_dataset
,
[
dataset_dir
,
training_stage
],
[
dataset
],
queue
=
False
)
dataset_dir
.
change
(
list_dataset
,
[
dataset_dir
,
training_stage
],
[
dataset
],
queue
=
False
)
input_elems
.
update
({
training_stage
,
dataset_dir
,
dataset
})
elem_dict
.
update
(
dict
(
training_stage
=
training_stage
,
dataset_dir
=
dataset_dir
,
dataset
=
dataset
,
**
preview_elems
))
with
gr
.
Row
():
cutoff_len
=
gr
.
Slider
(
value
=
1024
,
minimum
=
4
,
maximum
=
8192
,
step
=
1
)
learning_rate
=
gr
.
Textbox
(
value
=
"5e-5"
)
num_train_epochs
=
gr
.
Textbox
(
value
=
"3.0"
)
max_samples
=
gr
.
Textbox
(
value
=
"100000"
)
compute_type
=
gr
.
Radio
(
choices
=
[
"fp16"
,
"bf16"
,
"fp32"
],
value
=
"fp16"
)
input_elems
.
update
({
cutoff_len
,
learning_rate
,
num_train_epochs
,
max_samples
,
compute_type
})
elem_dict
.
update
(
dict
(
cutoff_len
=
cutoff_len
,
learning_rate
=
learning_rate
,
num_train_epochs
=
num_train_epochs
,
max_samples
=
max_samples
,
compute_type
=
compute_type
,
)
)
with
gr
.
Row
():
batch_size
=
gr
.
Slider
(
value
=
4
,
minimum
=
1
,
maximum
=
512
,
step
=
1
)
gradient_accumulation_steps
=
gr
.
Slider
(
value
=
4
,
minimum
=
1
,
maximum
=
512
,
step
=
1
)
lr_scheduler_type
=
gr
.
Dropdown
(
choices
=
[
scheduler
.
value
for
scheduler
in
SchedulerType
],
value
=
"cosine"
)
max_grad_norm
=
gr
.
Textbox
(
value
=
"1.0"
)
val_size
=
gr
.
Slider
(
value
=
0
,
minimum
=
0
,
maximum
=
1
,
step
=
0.001
)
input_elems
.
update
({
batch_size
,
gradient_accumulation_steps
,
lr_scheduler_type
,
max_grad_norm
,
val_size
})
elem_dict
.
update
(
dict
(
batch_size
=
batch_size
,
gradient_accumulation_steps
=
gradient_accumulation_steps
,
lr_scheduler_type
=
lr_scheduler_type
,
max_grad_norm
=
max_grad_norm
,
val_size
=
val_size
,
)
)
with
gr
.
Accordion
(
label
=
"Extra config"
,
open
=
False
)
as
extra_tab
:
with
gr
.
Row
():
logging_steps
=
gr
.
Slider
(
value
=
5
,
minimum
=
5
,
maximum
=
1000
,
step
=
5
)
save_steps
=
gr
.
Slider
(
value
=
100
,
minimum
=
10
,
maximum
=
5000
,
step
=
10
)
warmup_steps
=
gr
.
Slider
(
value
=
0
,
minimum
=
0
,
maximum
=
5000
,
step
=
1
)
neftune_alpha
=
gr
.
Slider
(
value
=
0
,
minimum
=
0
,
maximum
=
10
,
step
=
0.1
)
with
gr
.
Column
():
sft_packing
=
gr
.
Checkbox
(
value
=
False
)
upcast_layernorm
=
gr
.
Checkbox
(
value
=
False
)
input_elems
.
update
({
logging_steps
,
save_steps
,
warmup_steps
,
neftune_alpha
,
sft_packing
,
upcast_layernorm
})
elem_dict
.
update
(
dict
(
extra_tab
=
extra_tab
,
logging_steps
=
logging_steps
,
save_steps
=
save_steps
,
warmup_steps
=
warmup_steps
,
neftune_alpha
=
neftune_alpha
,
sft_packing
=
sft_packing
,
upcast_layernorm
=
upcast_layernorm
,
)
)
with
gr
.
Accordion
(
label
=
"LoRA config"
,
open
=
False
)
as
lora_tab
:
with
gr
.
Row
():
lora_rank
=
gr
.
Slider
(
value
=
8
,
minimum
=
1
,
maximum
=
1024
,
step
=
1
,
scale
=
1
)
lora_dropout
=
gr
.
Slider
(
value
=
0.1
,
minimum
=
0
,
maximum
=
1
,
step
=
0.01
,
scale
=
1
)
lora_target
=
gr
.
Textbox
(
scale
=
1
)
additional_target
=
gr
.
Textbox
(
scale
=
1
)
create_new_adapter
=
gr
.
Checkbox
(
scale
=
1
)
input_elems
.
update
({
lora_rank
,
lora_dropout
,
lora_target
,
additional_target
,
create_new_adapter
})
elem_dict
.
update
(
dict
(
lora_tab
=
lora_tab
,
lora_rank
=
lora_rank
,
lora_dropout
=
lora_dropout
,
lora_target
=
lora_target
,
additional_target
=
additional_target
,
create_new_adapter
=
create_new_adapter
,
)
)
with
gr
.
Accordion
(
label
=
"RLHF config"
,
open
=
False
)
as
rlhf_tab
:
with
gr
.
Row
():
dpo_beta
=
gr
.
Slider
(
value
=
0.1
,
minimum
=
0
,
maximum
=
1
,
step
=
0.01
,
scale
=
1
)
dpo_ftx
=
gr
.
Slider
(
value
=
0
,
minimum
=
0
,
maximum
=
10
,
step
=
0.01
,
scale
=
1
)
reward_model
=
gr
.
Dropdown
(
scale
=
2
,
allow_custom_value
=
True
)
refresh_btn
=
gr
.
Button
(
scale
=
1
)
refresh_btn
.
click
(
list_adapters
,
[
engine
.
manager
.
get_elem_by_name
(
"top.model_name"
),
engine
.
manager
.
get_elem_by_name
(
"top.finetuning_type"
)],
[
reward_model
],
queue
=
False
,
)
input_elems
.
update
({
dpo_beta
,
dpo_ftx
,
reward_model
})
elem_dict
.
update
(
dict
(
rlhf_tab
=
rlhf_tab
,
dpo_beta
=
dpo_beta
,
dpo_ftx
=
dpo_ftx
,
reward_model
=
reward_model
,
refresh_btn
=
refresh_btn
)
)
with
gr
.
Row
():
cmd_preview_btn
=
gr
.
Button
()
start_btn
=
gr
.
Button
()
stop_btn
=
gr
.
Button
()
with
gr
.
Row
():
with
gr
.
Column
(
scale
=
3
):
with
gr
.
Row
():
output_dir
=
gr
.
Textbox
()
with
gr
.
Row
():
resume_btn
=
gr
.
Checkbox
(
visible
=
False
,
interactive
=
False
,
value
=
False
)
process_bar
=
gr
.
Slider
(
visible
=
False
,
interactive
=
False
)
with
gr
.
Box
():
output_box
=
gr
.
Markdown
()
with
gr
.
Column
(
scale
=
1
):
loss_viewer
=
gr
.
Plot
()
input_elems
.
add
(
output_dir
)
output_elems
=
[
output_box
,
process_bar
]
cmd_preview_btn
.
click
(
engine
.
runner
.
preview_train
,
input_elems
,
output_elems
)
start_btn
.
click
(
engine
.
runner
.
run_train
,
input_elems
,
output_elems
)
stop_btn
.
click
(
engine
.
runner
.
set_abort
,
queue
=
False
)
resume_btn
.
change
(
engine
.
runner
.
monitor
,
outputs
=
output_elems
)
elem_dict
.
update
(
dict
(
cmd_preview_btn
=
cmd_preview_btn
,
start_btn
=
start_btn
,
stop_btn
=
stop_btn
,
output_dir
=
output_dir
,
resume_btn
=
resume_btn
,
process_bar
=
process_bar
,
output_box
=
output_box
,
loss_viewer
=
loss_viewer
,
)
)
output_box
.
change
(
gen_plot
,
[
engine
.
manager
.
get_elem_by_name
(
"top.model_name"
),
engine
.
manager
.
get_elem_by_name
(
"top.finetuning_type"
),
output_dir
,
],
loss_viewer
,
queue
=
False
,
)
return
elem_dict
LLaMA-Factory/src/llmtuner/webui/css.py
0 → 100644
View file @
afe180a6
CSS
=
r
"""
.duplicate-button {
margin: auto !important;
color: white !important;
background: black !important;
border-radius: 100vh !important;
}
.modal-box {
position: fixed !important;
top: 50%;
left: 50%;
transform: translate(-50%, -50%); /* center horizontally */
max-width: 1000px;
max-height: 750px;
overflow-y: auto;
background-color: var(--input-background-fill);
flex-wrap: nowrap !important;
border: 2px solid black !important;
z-index: 1000;
padding: 10px;
}
.dark .modal-box {
border: 2px solid white !important;
}
"""
Prev
1
…
6
7
8
9
10
11
12
13
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment