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
chenych
llama-grpo
Commits
c7c477c7
Commit
c7c477c7
authored
Sep 24, 2025
by
chenych
Browse files
add grpo
parents
Pipeline
#2942
failed with stages
in 0 seconds
Changes
282
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
5477 additions
and
0 deletions
+5477
-0
src/llamafactory/webui/components/footer.py
src/llamafactory/webui/components/footer.py
+45
-0
src/llamafactory/webui/components/infer.py
src/llamafactory/webui/components/infer.py
+76
-0
src/llamafactory/webui/components/top.py
src/llamafactory/webui/components/top.py
+82
-0
src/llamafactory/webui/components/train.py
src/llamafactory/webui/components/train.py
+447
-0
src/llamafactory/webui/control.py
src/llamafactory/webui/control.py
+224
-0
src/llamafactory/webui/css.py
src/llamafactory/webui/css.py
+67
-0
src/llamafactory/webui/engine.py
src/llamafactory/webui/engine.py
+83
-0
src/llamafactory/webui/interface.py
src/llamafactory/webui/interface.py
+106
-0
src/llamafactory/webui/locales.py
src/llamafactory/webui/locales.py
+3173
-0
src/llamafactory/webui/manager.py
src/llamafactory/webui/manager.py
+70
-0
src/llamafactory/webui/runner.py
src/llamafactory/webui/runner.py
+505
-0
src/train.py
src/train.py
+28
-0
src/webui.py
src/webui.py
+31
-0
tests/check_license.py
tests/check_license.py
+38
-0
tests/data/processor/test_feedback.py
tests/data/processor/test_feedback.py
+58
-0
tests/data/processor/test_pairwise.py
tests/data/processor/test_pairwise.py
+76
-0
tests/data/processor/test_processor_utils.py
tests/data/processor/test_processor_utils.py
+34
-0
tests/data/processor/test_supervised.py
tests/data/processor/test_supervised.py
+105
-0
tests/data/processor/test_unsupervised.py
tests/data/processor/test_unsupervised.py
+60
-0
tests/data/test_collator.py
tests/data/test_collator.py
+169
-0
No files found.
src/llamafactory/webui/components/footer.py
0 → 100644
View file @
c7c477c7
# Copyright 2025 the LlamaFactory team.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file 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.
from
typing
import
TYPE_CHECKING
from
...extras.misc
import
get_current_memory
from
...extras.packages
import
is_gradio_available
if
is_gradio_available
():
import
gradio
as
gr
if
TYPE_CHECKING
:
from
gradio.components
import
Component
def
get_device_memory
()
->
"gr.Slider"
:
free
,
total
=
get_current_memory
()
if
total
!=
-
1
:
used
=
round
((
total
-
free
)
/
(
1024
**
3
),
2
)
total
=
round
(
total
/
(
1024
**
3
),
2
)
return
gr
.
Slider
(
minimum
=
0
,
maximum
=
total
,
value
=
used
,
step
=
0.01
,
visible
=
True
)
else
:
return
gr
.
Slider
(
visible
=
False
)
def
create_footer
()
->
dict
[
str
,
"Component"
]:
with
gr
.
Row
():
device_memory
=
gr
.
Slider
(
visible
=
False
,
interactive
=
False
)
timer
=
gr
.
Timer
(
value
=
5
)
timer
.
tick
(
get_device_memory
,
outputs
=
[
device_memory
],
queue
=
False
)
return
dict
(
device_memory
=
device_memory
)
src/llamafactory/webui/components/infer.py
0 → 100644
View file @
c7c477c7
# Copyright 2025 the LlamaFactory team.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file 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.
from
typing
import
TYPE_CHECKING
from
...extras.packages
import
is_gradio_available
from
..common
import
is_multimodal
from
.chatbot
import
create_chat_box
if
is_gradio_available
():
import
gradio
as
gr
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
():
infer_backend
=
gr
.
Dropdown
(
choices
=
[
"huggingface"
,
"vllm"
,
"sglang"
],
value
=
"huggingface"
)
infer_dtype
=
gr
.
Dropdown
(
choices
=
[
"auto"
,
"float16"
,
"bfloat16"
,
"float32"
],
value
=
"auto"
)
extra_args
=
gr
.
Textbox
(
value
=
'{"vllm_enforce_eager": true}'
)
with
gr
.
Row
():
load_btn
=
gr
.
Button
()
unload_btn
=
gr
.
Button
()
info_box
=
gr
.
Textbox
(
show_label
=
False
,
interactive
=
False
)
input_elems
.
update
({
infer_backend
,
infer_dtype
,
extra_args
})
elem_dict
.
update
(
dict
(
infer_backend
=
infer_backend
,
infer_dtype
=
infer_dtype
,
extra_args
=
extra_args
,
load_btn
=
load_btn
,
unload_btn
=
unload_btn
,
info_box
=
info_box
,
)
)
chatbot
,
messages
,
chat_elems
=
create_chat_box
(
engine
,
visible
=
False
)
elem_dict
.
update
(
chat_elems
)
load_btn
.
click
(
engine
.
chatter
.
load_model
,
input_elems
,
[
info_box
]).
then
(
lambda
:
gr
.
Column
(
visible
=
engine
.
chatter
.
loaded
),
outputs
=
[
chat_elems
[
"chat_box"
]]
)
unload_btn
.
click
(
engine
.
chatter
.
unload_model
,
input_elems
,
[
info_box
]).
then
(
lambda
:
([],
[]),
outputs
=
[
chatbot
,
messages
]
).
then
(
lambda
:
gr
.
Column
(
visible
=
engine
.
chatter
.
loaded
),
outputs
=
[
chat_elems
[
"chat_box"
]])
engine
.
manager
.
get_elem_by_id
(
"top.model_name"
).
change
(
lambda
model_name
:
gr
.
Column
(
visible
=
is_multimodal
(
model_name
)),
[
engine
.
manager
.
get_elem_by_id
(
"top.model_name"
)],
[
chat_elems
[
"mm_box"
]],
)
return
elem_dict
src/llamafactory/webui/components/top.py
0 → 100644
View file @
c7c477c7
# Copyright 2025 the LlamaFactory team.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file 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.
from
typing
import
TYPE_CHECKING
from
...data
import
TEMPLATES
from
...extras.constants
import
METHODS
,
SUPPORTED_MODELS
from
...extras.misc
import
use_modelscope
,
use_openmind
from
...extras.packages
import
is_gradio_available
from
..common
import
save_config
from
..control
import
can_quantize
,
can_quantize_to
,
check_template
,
get_model_info
,
list_checkpoints
,
switch_hub
if
is_gradio_available
():
import
gradio
as
gr
if
TYPE_CHECKING
:
from
gradio.components
import
Component
def
create_top
()
->
dict
[
str
,
"Component"
]:
with
gr
.
Row
():
lang
=
gr
.
Dropdown
(
choices
=
[
"en"
,
"ru"
,
"zh"
,
"ko"
,
"ja"
],
value
=
None
,
scale
=
1
)
available_models
=
list
(
SUPPORTED_MODELS
.
keys
())
+
[
"Custom"
]
model_name
=
gr
.
Dropdown
(
choices
=
available_models
,
value
=
None
,
scale
=
2
)
model_path
=
gr
.
Textbox
(
scale
=
2
)
default_hub
=
"modelscope"
if
use_modelscope
()
else
"openmind"
if
use_openmind
()
else
"huggingface"
hub_name
=
gr
.
Dropdown
(
choices
=
[
"huggingface"
,
"modelscope"
,
"openmind"
],
value
=
default_hub
,
scale
=
2
)
with
gr
.
Row
():
finetuning_type
=
gr
.
Dropdown
(
choices
=
METHODS
,
value
=
"lora"
,
scale
=
1
)
checkpoint_path
=
gr
.
Dropdown
(
multiselect
=
True
,
allow_custom_value
=
True
,
scale
=
6
)
with
gr
.
Row
():
quantization_bit
=
gr
.
Dropdown
(
choices
=
[
"none"
,
"8"
,
"4"
],
value
=
"none"
,
allow_custom_value
=
True
)
quantization_method
=
gr
.
Dropdown
(
choices
=
[
"bnb"
,
"hqq"
,
"eetq"
],
value
=
"bnb"
)
template
=
gr
.
Dropdown
(
choices
=
list
(
TEMPLATES
.
keys
()),
value
=
"default"
)
rope_scaling
=
gr
.
Dropdown
(
choices
=
[
"none"
,
"linear"
,
"dynamic"
,
"yarn"
,
"llama3"
],
value
=
"none"
)
booster
=
gr
.
Dropdown
(
choices
=
[
"auto"
,
"flashattn2"
,
"unsloth"
,
"liger_kernel"
],
value
=
"auto"
)
model_name
.
change
(
get_model_info
,
[
model_name
],
[
model_path
,
template
],
queue
=
False
).
then
(
list_checkpoints
,
[
model_name
,
finetuning_type
],
[
checkpoint_path
],
queue
=
False
).
then
(
check_template
,
[
lang
,
template
])
model_name
.
input
(
save_config
,
inputs
=
[
lang
,
hub_name
,
model_name
],
queue
=
False
)
model_path
.
input
(
save_config
,
inputs
=
[
lang
,
hub_name
,
model_name
,
model_path
],
queue
=
False
)
finetuning_type
.
change
(
can_quantize
,
[
finetuning_type
],
[
quantization_bit
],
queue
=
False
).
then
(
list_checkpoints
,
[
model_name
,
finetuning_type
],
[
checkpoint_path
],
queue
=
False
)
checkpoint_path
.
focus
(
list_checkpoints
,
[
model_name
,
finetuning_type
],
[
checkpoint_path
],
queue
=
False
)
quantization_method
.
change
(
can_quantize_to
,
[
quantization_method
],
[
quantization_bit
],
queue
=
False
)
hub_name
.
change
(
switch_hub
,
inputs
=
[
hub_name
],
queue
=
False
).
then
(
get_model_info
,
[
model_name
],
[
model_path
,
template
],
queue
=
False
).
then
(
list_checkpoints
,
[
model_name
,
finetuning_type
],
[
checkpoint_path
],
queue
=
False
).
then
(
check_template
,
[
lang
,
template
]
)
hub_name
.
input
(
save_config
,
inputs
=
[
lang
,
hub_name
],
queue
=
False
)
return
dict
(
lang
=
lang
,
model_name
=
model_name
,
model_path
=
model_path
,
hub_name
=
hub_name
,
finetuning_type
=
finetuning_type
,
checkpoint_path
=
checkpoint_path
,
quantization_bit
=
quantization_bit
,
quantization_method
=
quantization_method
,
template
=
template
,
rope_scaling
=
rope_scaling
,
booster
=
booster
,
)
src/llamafactory/webui/components/train.py
0 → 100644
View file @
c7c477c7
# Copyright 2025 the LlamaFactory team.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file 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.
from
typing
import
TYPE_CHECKING
from
transformers.trainer_utils
import
SchedulerType
from
...extras.constants
import
TRAINING_STAGES
from
...extras.misc
import
get_device_count
from
...extras.packages
import
is_gradio_available
from
..common
import
DEFAULT_DATA_DIR
from
..control
import
change_stage
,
list_checkpoints
,
list_config_paths
,
list_datasets
,
list_output_dirs
from
.data
import
create_preview_box
if
is_gradio_available
():
import
gradio
as
gr
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
():
stages
=
list
(
TRAINING_STAGES
.
keys
())
training_stage
=
gr
.
Dropdown
(
choices
=
stages
,
value
=
stages
[
0
],
scale
=
1
)
dataset_dir
=
gr
.
Textbox
(
value
=
DEFAULT_DATA_DIR
,
scale
=
1
)
dataset
=
gr
.
Dropdown
(
multiselect
=
True
,
allow_custom_value
=
True
,
scale
=
4
)
preview_elems
=
create_preview_box
(
dataset_dir
,
dataset
)
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
():
learning_rate
=
gr
.
Textbox
(
value
=
"5e-5"
)
num_train_epochs
=
gr
.
Textbox
(
value
=
"3.0"
)
max_grad_norm
=
gr
.
Textbox
(
value
=
"1.0"
)
max_samples
=
gr
.
Textbox
(
value
=
"100000"
)
compute_type
=
gr
.
Dropdown
(
choices
=
[
"bf16"
,
"fp16"
,
"fp32"
,
"pure_bf16"
],
value
=
"bf16"
)
input_elems
.
update
({
learning_rate
,
num_train_epochs
,
max_grad_norm
,
max_samples
,
compute_type
})
elem_dict
.
update
(
dict
(
learning_rate
=
learning_rate
,
num_train_epochs
=
num_train_epochs
,
max_grad_norm
=
max_grad_norm
,
max_samples
=
max_samples
,
compute_type
=
compute_type
,
)
)
with
gr
.
Row
():
cutoff_len
=
gr
.
Slider
(
minimum
=
4
,
maximum
=
131072
,
value
=
2048
,
step
=
1
)
batch_size
=
gr
.
Slider
(
minimum
=
1
,
maximum
=
1024
,
value
=
2
,
step
=
1
)
gradient_accumulation_steps
=
gr
.
Slider
(
minimum
=
1
,
maximum
=
1024
,
value
=
8
,
step
=
1
)
val_size
=
gr
.
Slider
(
minimum
=
0
,
maximum
=
1
,
value
=
0
,
step
=
0.001
)
lr_scheduler_type
=
gr
.
Dropdown
(
choices
=
[
scheduler
.
value
for
scheduler
in
SchedulerType
],
value
=
"cosine"
)
input_elems
.
update
({
cutoff_len
,
batch_size
,
gradient_accumulation_steps
,
val_size
,
lr_scheduler_type
})
elem_dict
.
update
(
dict
(
cutoff_len
=
cutoff_len
,
batch_size
=
batch_size
,
gradient_accumulation_steps
=
gradient_accumulation_steps
,
val_size
=
val_size
,
lr_scheduler_type
=
lr_scheduler_type
,
)
)
with
gr
.
Accordion
(
open
=
False
)
as
extra_tab
:
with
gr
.
Row
():
logging_steps
=
gr
.
Slider
(
minimum
=
1
,
maximum
=
1000
,
value
=
5
,
step
=
5
)
save_steps
=
gr
.
Slider
(
minimum
=
10
,
maximum
=
5000
,
value
=
100
,
step
=
10
)
warmup_steps
=
gr
.
Slider
(
minimum
=
0
,
maximum
=
5000
,
value
=
0
,
step
=
1
)
neftune_alpha
=
gr
.
Slider
(
minimum
=
0
,
maximum
=
10
,
value
=
0
,
step
=
0.1
)
extra_args
=
gr
.
Textbox
(
value
=
'{"optim": "adamw_torch"}'
)
with
gr
.
Row
():
with
gr
.
Column
():
packing
=
gr
.
Checkbox
()
neat_packing
=
gr
.
Checkbox
()
with
gr
.
Column
():
train_on_prompt
=
gr
.
Checkbox
()
mask_history
=
gr
.
Checkbox
()
with
gr
.
Column
():
resize_vocab
=
gr
.
Checkbox
()
use_llama_pro
=
gr
.
Checkbox
()
with
gr
.
Column
():
enable_thinking
=
gr
.
Checkbox
(
value
=
True
)
report_to
=
gr
.
Dropdown
(
choices
=
[
"none"
,
"wandb"
,
"mlflow"
,
"neptune"
,
"tensorboard"
,
"all"
],
value
=
"none"
,
allow_custom_value
=
True
,
)
input_elems
.
update
(
{
logging_steps
,
save_steps
,
warmup_steps
,
neftune_alpha
,
extra_args
,
packing
,
neat_packing
,
train_on_prompt
,
mask_history
,
resize_vocab
,
use_llama_pro
,
enable_thinking
,
report_to
,
}
)
elem_dict
.
update
(
dict
(
extra_tab
=
extra_tab
,
logging_steps
=
logging_steps
,
save_steps
=
save_steps
,
warmup_steps
=
warmup_steps
,
neftune_alpha
=
neftune_alpha
,
extra_args
=
extra_args
,
packing
=
packing
,
neat_packing
=
neat_packing
,
train_on_prompt
=
train_on_prompt
,
mask_history
=
mask_history
,
resize_vocab
=
resize_vocab
,
use_llama_pro
=
use_llama_pro
,
enable_thinking
=
enable_thinking
,
report_to
=
report_to
,
)
)
with
gr
.
Accordion
(
open
=
False
)
as
freeze_tab
:
with
gr
.
Row
():
freeze_trainable_layers
=
gr
.
Slider
(
minimum
=-
128
,
maximum
=
128
,
value
=
2
,
step
=
1
)
freeze_trainable_modules
=
gr
.
Textbox
(
value
=
"all"
)
freeze_extra_modules
=
gr
.
Textbox
()
input_elems
.
update
({
freeze_trainable_layers
,
freeze_trainable_modules
,
freeze_extra_modules
})
elem_dict
.
update
(
dict
(
freeze_tab
=
freeze_tab
,
freeze_trainable_layers
=
freeze_trainable_layers
,
freeze_trainable_modules
=
freeze_trainable_modules
,
freeze_extra_modules
=
freeze_extra_modules
,
)
)
with
gr
.
Accordion
(
open
=
False
)
as
lora_tab
:
with
gr
.
Row
():
lora_rank
=
gr
.
Slider
(
minimum
=
1
,
maximum
=
1024
,
value
=
8
,
step
=
1
)
lora_alpha
=
gr
.
Slider
(
minimum
=
1
,
maximum
=
2048
,
value
=
16
,
step
=
1
)
lora_dropout
=
gr
.
Slider
(
minimum
=
0
,
maximum
=
1
,
value
=
0
,
step
=
0.01
)
loraplus_lr_ratio
=
gr
.
Slider
(
minimum
=
0
,
maximum
=
64
,
value
=
0
,
step
=
0.01
)
create_new_adapter
=
gr
.
Checkbox
()
with
gr
.
Row
():
use_rslora
=
gr
.
Checkbox
()
use_dora
=
gr
.
Checkbox
()
use_pissa
=
gr
.
Checkbox
()
lora_target
=
gr
.
Textbox
(
scale
=
2
)
additional_target
=
gr
.
Textbox
(
scale
=
2
)
input_elems
.
update
(
{
lora_rank
,
lora_alpha
,
lora_dropout
,
loraplus_lr_ratio
,
create_new_adapter
,
use_rslora
,
use_dora
,
use_pissa
,
lora_target
,
additional_target
,
}
)
elem_dict
.
update
(
dict
(
lora_tab
=
lora_tab
,
lora_rank
=
lora_rank
,
lora_alpha
=
lora_alpha
,
lora_dropout
=
lora_dropout
,
loraplus_lr_ratio
=
loraplus_lr_ratio
,
create_new_adapter
=
create_new_adapter
,
use_rslora
=
use_rslora
,
use_dora
=
use_dora
,
use_pissa
=
use_pissa
,
lora_target
=
lora_target
,
additional_target
=
additional_target
,
)
)
with
gr
.
Accordion
(
open
=
False
)
as
rlhf_tab
:
with
gr
.
Row
():
pref_beta
=
gr
.
Slider
(
minimum
=
0
,
maximum
=
1
,
value
=
0.1
,
step
=
0.01
)
pref_ftx
=
gr
.
Slider
(
minimum
=
0
,
maximum
=
10
,
value
=
0
,
step
=
0.01
)
pref_loss
=
gr
.
Dropdown
(
choices
=
[
"sigmoid"
,
"hinge"
,
"ipo"
,
"kto_pair"
,
"orpo"
,
"simpo"
],
value
=
"sigmoid"
)
reward_model
=
gr
.
Dropdown
(
multiselect
=
True
,
allow_custom_value
=
True
)
with
gr
.
Column
():
ppo_score_norm
=
gr
.
Checkbox
()
ppo_whiten_rewards
=
gr
.
Checkbox
()
input_elems
.
update
({
pref_beta
,
pref_ftx
,
pref_loss
,
reward_model
,
ppo_score_norm
,
ppo_whiten_rewards
})
elem_dict
.
update
(
dict
(
rlhf_tab
=
rlhf_tab
,
pref_beta
=
pref_beta
,
pref_ftx
=
pref_ftx
,
pref_loss
=
pref_loss
,
reward_model
=
reward_model
,
ppo_score_norm
=
ppo_score_norm
,
ppo_whiten_rewards
=
ppo_whiten_rewards
,
)
)
with
gr
.
Accordion
(
open
=
False
)
as
mm_tab
:
with
gr
.
Row
():
freeze_vision_tower
=
gr
.
Checkbox
(
value
=
True
)
freeze_multi_modal_projector
=
gr
.
Checkbox
(
value
=
True
)
freeze_language_model
=
gr
.
Checkbox
(
value
=
False
)
with
gr
.
Row
():
image_max_pixels
=
gr
.
Textbox
(
value
=
"768*768"
)
image_min_pixels
=
gr
.
Textbox
(
value
=
"32*32"
)
video_max_pixels
=
gr
.
Textbox
(
value
=
"256*256"
)
video_min_pixels
=
gr
.
Textbox
(
value
=
"16*16"
)
input_elems
.
update
(
{
freeze_vision_tower
,
freeze_multi_modal_projector
,
freeze_language_model
,
image_max_pixels
,
image_min_pixels
,
video_max_pixels
,
video_min_pixels
,
}
)
elem_dict
.
update
(
dict
(
mm_tab
=
mm_tab
,
freeze_vision_tower
=
freeze_vision_tower
,
freeze_multi_modal_projector
=
freeze_multi_modal_projector
,
freeze_language_model
=
freeze_language_model
,
image_max_pixels
=
image_max_pixels
,
image_min_pixels
=
image_min_pixels
,
video_max_pixels
=
video_max_pixels
,
video_min_pixels
=
video_min_pixels
,
)
)
with
gr
.
Accordion
(
open
=
False
)
as
galore_tab
:
with
gr
.
Row
():
use_galore
=
gr
.
Checkbox
()
galore_rank
=
gr
.
Slider
(
minimum
=
1
,
maximum
=
1024
,
value
=
16
,
step
=
1
)
galore_update_interval
=
gr
.
Slider
(
minimum
=
1
,
maximum
=
2048
,
value
=
200
,
step
=
1
)
galore_scale
=
gr
.
Slider
(
minimum
=
0
,
maximum
=
100
,
value
=
2.0
,
step
=
0.1
)
galore_target
=
gr
.
Textbox
(
value
=
"all"
)
input_elems
.
update
({
use_galore
,
galore_rank
,
galore_update_interval
,
galore_scale
,
galore_target
})
elem_dict
.
update
(
dict
(
galore_tab
=
galore_tab
,
use_galore
=
use_galore
,
galore_rank
=
galore_rank
,
galore_update_interval
=
galore_update_interval
,
galore_scale
=
galore_scale
,
galore_target
=
galore_target
,
)
)
with
gr
.
Accordion
(
open
=
False
)
as
apollo_tab
:
with
gr
.
Row
():
use_apollo
=
gr
.
Checkbox
()
apollo_rank
=
gr
.
Slider
(
minimum
=
1
,
maximum
=
1024
,
value
=
16
,
step
=
1
)
apollo_update_interval
=
gr
.
Slider
(
minimum
=
1
,
maximum
=
2048
,
value
=
200
,
step
=
1
)
apollo_scale
=
gr
.
Slider
(
minimum
=
0
,
maximum
=
100
,
value
=
32.0
,
step
=
0.1
)
apollo_target
=
gr
.
Textbox
(
value
=
"all"
)
input_elems
.
update
({
use_apollo
,
apollo_rank
,
apollo_update_interval
,
apollo_scale
,
apollo_target
})
elem_dict
.
update
(
dict
(
apollo_tab
=
apollo_tab
,
use_apollo
=
use_apollo
,
apollo_rank
=
apollo_rank
,
apollo_update_interval
=
apollo_update_interval
,
apollo_scale
=
apollo_scale
,
apollo_target
=
apollo_target
,
)
)
with
gr
.
Accordion
(
open
=
False
)
as
badam_tab
:
with
gr
.
Row
():
use_badam
=
gr
.
Checkbox
()
badam_mode
=
gr
.
Dropdown
(
choices
=
[
"layer"
,
"ratio"
],
value
=
"layer"
)
badam_switch_mode
=
gr
.
Dropdown
(
choices
=
[
"ascending"
,
"descending"
,
"random"
,
"fixed"
],
value
=
"ascending"
)
badam_switch_interval
=
gr
.
Slider
(
minimum
=
1
,
maximum
=
1024
,
value
=
50
,
step
=
1
)
badam_update_ratio
=
gr
.
Slider
(
minimum
=
0
,
maximum
=
1
,
value
=
0.05
,
step
=
0.01
)
input_elems
.
update
({
use_badam
,
badam_mode
,
badam_switch_mode
,
badam_switch_interval
,
badam_update_ratio
})
elem_dict
.
update
(
dict
(
badam_tab
=
badam_tab
,
use_badam
=
use_badam
,
badam_mode
=
badam_mode
,
badam_switch_mode
=
badam_switch_mode
,
badam_switch_interval
=
badam_switch_interval
,
badam_update_ratio
=
badam_update_ratio
,
)
)
with
gr
.
Accordion
(
open
=
False
)
as
swanlab_tab
:
with
gr
.
Row
():
use_swanlab
=
gr
.
Checkbox
()
swanlab_project
=
gr
.
Textbox
(
value
=
"llamafactory"
)
swanlab_run_name
=
gr
.
Textbox
()
swanlab_workspace
=
gr
.
Textbox
()
swanlab_api_key
=
gr
.
Textbox
()
swanlab_mode
=
gr
.
Dropdown
(
choices
=
[
"cloud"
,
"local"
],
value
=
"cloud"
)
swanlab_link
=
gr
.
Markdown
(
visible
=
False
)
input_elems
.
update
(
{
use_swanlab
,
swanlab_project
,
swanlab_run_name
,
swanlab_workspace
,
swanlab_api_key
,
swanlab_mode
,
swanlab_link
,
}
)
elem_dict
.
update
(
dict
(
swanlab_tab
=
swanlab_tab
,
use_swanlab
=
use_swanlab
,
swanlab_project
=
swanlab_project
,
swanlab_run_name
=
swanlab_run_name
,
swanlab_workspace
=
swanlab_workspace
,
swanlab_api_key
=
swanlab_api_key
,
swanlab_mode
=
swanlab_mode
,
swanlab_link
=
swanlab_link
,
)
)
with
gr
.
Row
():
cmd_preview_btn
=
gr
.
Button
()
arg_save_btn
=
gr
.
Button
()
arg_load_btn
=
gr
.
Button
()
start_btn
=
gr
.
Button
(
variant
=
"primary"
)
stop_btn
=
gr
.
Button
(
variant
=
"stop"
)
with
gr
.
Row
():
with
gr
.
Column
(
scale
=
3
):
with
gr
.
Row
():
current_time
=
gr
.
Textbox
(
visible
=
False
,
interactive
=
False
)
output_dir
=
gr
.
Dropdown
(
allow_custom_value
=
True
)
config_path
=
gr
.
Dropdown
(
allow_custom_value
=
True
)
with
gr
.
Row
():
device_count
=
gr
.
Textbox
(
value
=
str
(
get_device_count
()
or
1
),
interactive
=
False
)
ds_stage
=
gr
.
Dropdown
(
choices
=
[
"none"
,
"2"
,
"3"
],
value
=
"none"
)
ds_offload
=
gr
.
Checkbox
()
with
gr
.
Row
():
resume_btn
=
gr
.
Checkbox
(
visible
=
False
,
interactive
=
False
)
progress_bar
=
gr
.
Slider
(
visible
=
False
,
interactive
=
False
)
with
gr
.
Row
():
output_box
=
gr
.
Markdown
()
with
gr
.
Column
(
scale
=
1
):
loss_viewer
=
gr
.
Plot
()
input_elems
.
update
({
output_dir
,
config_path
,
ds_stage
,
ds_offload
})
elem_dict
.
update
(
dict
(
cmd_preview_btn
=
cmd_preview_btn
,
arg_save_btn
=
arg_save_btn
,
arg_load_btn
=
arg_load_btn
,
start_btn
=
start_btn
,
stop_btn
=
stop_btn
,
current_time
=
current_time
,
output_dir
=
output_dir
,
config_path
=
config_path
,
device_count
=
device_count
,
ds_stage
=
ds_stage
,
ds_offload
=
ds_offload
,
resume_btn
=
resume_btn
,
progress_bar
=
progress_bar
,
output_box
=
output_box
,
loss_viewer
=
loss_viewer
,
)
)
output_elems
=
[
output_box
,
progress_bar
,
loss_viewer
,
swanlab_link
]
cmd_preview_btn
.
click
(
engine
.
runner
.
preview_train
,
input_elems
,
output_elems
,
concurrency_limit
=
None
)
start_btn
.
click
(
engine
.
runner
.
run_train
,
input_elems
,
output_elems
)
stop_btn
.
click
(
engine
.
runner
.
set_abort
)
resume_btn
.
change
(
engine
.
runner
.
monitor
,
outputs
=
output_elems
,
concurrency_limit
=
None
)
lang
=
engine
.
manager
.
get_elem_by_id
(
"top.lang"
)
model_name
:
gr
.
Dropdown
=
engine
.
manager
.
get_elem_by_id
(
"top.model_name"
)
finetuning_type
:
gr
.
Dropdown
=
engine
.
manager
.
get_elem_by_id
(
"top.finetuning_type"
)
arg_save_btn
.
click
(
engine
.
runner
.
save_args
,
input_elems
,
output_elems
,
concurrency_limit
=
None
)
arg_load_btn
.
click
(
engine
.
runner
.
load_args
,
[
lang
,
config_path
],
list
(
input_elems
)
+
[
output_box
],
concurrency_limit
=
None
)
dataset
.
focus
(
list_datasets
,
[
dataset_dir
,
training_stage
],
[
dataset
],
queue
=
False
)
training_stage
.
change
(
change_stage
,
[
training_stage
],
[
dataset
,
packing
],
queue
=
False
)
reward_model
.
focus
(
list_checkpoints
,
[
model_name
,
finetuning_type
],
[
reward_model
],
queue
=
False
)
model_name
.
change
(
list_output_dirs
,
[
model_name
,
finetuning_type
,
current_time
],
[
output_dir
],
queue
=
False
)
finetuning_type
.
change
(
list_output_dirs
,
[
model_name
,
finetuning_type
,
current_time
],
[
output_dir
],
queue
=
False
)
output_dir
.
change
(
list_output_dirs
,
[
model_name
,
finetuning_type
,
current_time
],
[
output_dir
],
concurrency_limit
=
None
)
output_dir
.
input
(
engine
.
runner
.
check_output_dir
,
[
lang
,
model_name
,
finetuning_type
,
output_dir
],
list
(
input_elems
)
+
[
output_box
],
concurrency_limit
=
None
,
)
config_path
.
change
(
list_config_paths
,
[
current_time
],
[
config_path
],
queue
=
False
)
return
elem_dict
src/llamafactory/webui/control.py
0 → 100644
View file @
c7c477c7
# Copyright 2025 the LlamaFactory team.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file 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.
import
json
import
os
from
typing
import
Any
,
Optional
from
transformers.trainer_utils
import
get_last_checkpoint
from
..extras.constants
import
(
CHECKPOINT_NAMES
,
PEFT_METHODS
,
RUNNING_LOG
,
STAGES_USE_PAIR_DATA
,
SWANLAB_CONFIG
,
TRAINER_LOG
,
TRAINING_STAGES
,
)
from
..extras.packages
import
is_gradio_available
,
is_matplotlib_available
from
..extras.ploting
import
gen_loss_plot
from
..model
import
QuantizationMethod
from
.common
import
DEFAULT_CONFIG_DIR
,
DEFAULT_DATA_DIR
,
get_model_path
,
get_save_dir
,
get_template
,
load_dataset_info
from
.locales
import
ALERTS
if
is_gradio_available
():
import
gradio
as
gr
def
switch_hub
(
hub_name
:
str
)
->
None
:
r
"""Switch model hub.
Inputs: top.hub_name
"""
os
.
environ
[
"USE_MODELSCOPE_HUB"
]
=
"1"
if
hub_name
==
"modelscope"
else
"0"
os
.
environ
[
"USE_OPENMIND_HUB"
]
=
"1"
if
hub_name
==
"openmind"
else
"0"
def
can_quantize
(
finetuning_type
:
str
)
->
"gr.Dropdown"
:
r
"""Judge if the quantization is available in this finetuning type.
Inputs: top.finetuning_type
Outputs: top.quantization_bit
"""
if
finetuning_type
not
in
PEFT_METHODS
:
return
gr
.
Dropdown
(
value
=
"none"
,
interactive
=
False
)
else
:
return
gr
.
Dropdown
(
interactive
=
True
)
def
can_quantize_to
(
quantization_method
:
str
)
->
"gr.Dropdown"
:
r
"""Get the available quantization bits.
Inputs: top.quantization_method
Outputs: top.quantization_bit
"""
if
quantization_method
==
QuantizationMethod
.
BNB
:
available_bits
=
[
"none"
,
"8"
,
"4"
]
elif
quantization_method
==
QuantizationMethod
.
HQQ
:
available_bits
=
[
"none"
,
"8"
,
"6"
,
"5"
,
"4"
,
"3"
,
"2"
,
"1"
]
elif
quantization_method
==
QuantizationMethod
.
EETQ
:
available_bits
=
[
"none"
,
"8"
]
return
gr
.
Dropdown
(
choices
=
available_bits
)
def
change_stage
(
training_stage
:
str
=
list
(
TRAINING_STAGES
.
keys
())[
0
])
->
tuple
[
list
[
str
],
bool
]:
r
"""Modify states after changing the training stage.
Inputs: train.training_stage
Outputs: train.dataset, train.packing
"""
return
[],
TRAINING_STAGES
[
training_stage
]
==
"pt"
def
get_model_info
(
model_name
:
str
)
->
tuple
[
str
,
str
]:
r
"""Get the necessary information of this model.
Inputs: top.model_name
Outputs: top.model_path, top.template
"""
return
get_model_path
(
model_name
),
get_template
(
model_name
)
def
check_template
(
lang
:
str
,
template
:
str
)
->
None
:
r
"""Check if an instruct model is used.
Please use queue=True to show the warning message.
Inputs: top.lang, top.template
"""
if
template
==
"default"
:
gr
.
Warning
(
ALERTS
[
"warn_no_instruct"
][
lang
])
def
get_trainer_info
(
lang
:
str
,
output_path
:
os
.
PathLike
,
do_train
:
bool
)
->
tuple
[
str
,
"gr.Slider"
,
dict
[
str
,
Any
]]:
r
"""Get training infomation for monitor.
If do_train is True:
Inputs: top.lang, train.output_path
Outputs: train.output_box, train.progress_bar, train.loss_viewer, train.swanlab_link
If do_train is False:
Inputs: top.lang, eval.output_path
Outputs: eval.output_box, eval.progress_bar, None, None
"""
running_log
=
""
running_progress
=
gr
.
Slider
(
visible
=
False
)
running_info
=
{}
running_log_path
=
os
.
path
.
join
(
output_path
,
RUNNING_LOG
)
if
os
.
path
.
isfile
(
running_log_path
):
with
open
(
running_log_path
,
encoding
=
"utf-8"
)
as
f
:
running_log
=
"```
\n
"
+
f
.
read
()[
-
20000
:]
+
"
\n
```
\n
"
# avoid lengthy log
trainer_log_path
=
os
.
path
.
join
(
output_path
,
TRAINER_LOG
)
if
os
.
path
.
isfile
(
trainer_log_path
):
trainer_log
:
list
[
dict
[
str
,
Any
]]
=
[]
with
open
(
trainer_log_path
,
encoding
=
"utf-8"
)
as
f
:
for
line
in
f
:
trainer_log
.
append
(
json
.
loads
(
line
))
if
len
(
trainer_log
)
!=
0
:
latest_log
=
trainer_log
[
-
1
]
percentage
=
latest_log
[
"percentage"
]
label
=
"Running {:d}/{:d}: {} < {}"
.
format
(
latest_log
[
"current_steps"
],
latest_log
[
"total_steps"
],
latest_log
[
"elapsed_time"
],
latest_log
[
"remaining_time"
],
)
running_progress
=
gr
.
Slider
(
label
=
label
,
value
=
percentage
,
visible
=
True
)
if
do_train
and
is_matplotlib_available
():
running_info
[
"loss_viewer"
]
=
gr
.
Plot
(
gen_loss_plot
(
trainer_log
))
swanlab_config_path
=
os
.
path
.
join
(
output_path
,
SWANLAB_CONFIG
)
if
os
.
path
.
isfile
(
swanlab_config_path
):
with
open
(
swanlab_config_path
,
encoding
=
"utf-8"
)
as
f
:
swanlab_public_config
=
json
.
load
(
f
)
swanlab_link
=
swanlab_public_config
[
"cloud"
][
"experiment_url"
]
if
swanlab_link
is
not
None
:
running_info
[
"swanlab_link"
]
=
gr
.
Markdown
(
ALERTS
[
"info_swanlab_link"
][
lang
]
+
swanlab_link
,
visible
=
True
)
return
running_log
,
running_progress
,
running_info
def
list_checkpoints
(
model_name
:
str
,
finetuning_type
:
str
)
->
"gr.Dropdown"
:
r
"""List all available checkpoints.
Inputs: top.model_name, top.finetuning_type
Outputs: top.checkpoint_path
"""
checkpoints
=
[]
if
model_name
:
save_dir
=
get_save_dir
(
model_name
,
finetuning_type
)
if
save_dir
and
os
.
path
.
isdir
(
save_dir
):
for
checkpoint
in
os
.
listdir
(
save_dir
):
if
os
.
path
.
isdir
(
os
.
path
.
join
(
save_dir
,
checkpoint
))
and
any
(
os
.
path
.
isfile
(
os
.
path
.
join
(
save_dir
,
checkpoint
,
name
))
for
name
in
CHECKPOINT_NAMES
):
checkpoints
.
append
(
checkpoint
)
if
finetuning_type
in
PEFT_METHODS
:
return
gr
.
Dropdown
(
value
=
[],
choices
=
checkpoints
,
multiselect
=
True
)
else
:
return
gr
.
Dropdown
(
value
=
None
,
choices
=
checkpoints
,
multiselect
=
False
)
def
list_config_paths
(
current_time
:
str
)
->
"gr.Dropdown"
:
r
"""List all the saved configuration files.
Inputs: train.current_time
Outputs: train.config_path
"""
config_files
=
[
f
"
{
current_time
}
.yaml"
]
if
os
.
path
.
isdir
(
DEFAULT_CONFIG_DIR
):
for
file_name
in
os
.
listdir
(
DEFAULT_CONFIG_DIR
):
if
file_name
.
endswith
(
".yaml"
)
and
file_name
not
in
config_files
:
config_files
.
append
(
file_name
)
return
gr
.
Dropdown
(
choices
=
config_files
)
def
list_datasets
(
dataset_dir
:
str
=
None
,
training_stage
:
str
=
list
(
TRAINING_STAGES
.
keys
())[
0
])
->
"gr.Dropdown"
:
r
"""List all available datasets in the dataset dir for the training stage.
Inputs: *.dataset_dir, *.training_stage
Outputs: *.dataset
"""
dataset_info
=
load_dataset_info
(
dataset_dir
if
dataset_dir
is
not
None
else
DEFAULT_DATA_DIR
)
ranking
=
TRAINING_STAGES
[
training_stage
]
in
STAGES_USE_PAIR_DATA
datasets
=
[
k
for
k
,
v
in
dataset_info
.
items
()
if
v
.
get
(
"ranking"
,
False
)
==
ranking
]
return
gr
.
Dropdown
(
choices
=
datasets
)
def
list_output_dirs
(
model_name
:
Optional
[
str
],
finetuning_type
:
str
,
current_time
:
str
)
->
"gr.Dropdown"
:
r
"""List all the directories that can resume from.
Inputs: top.model_name, top.finetuning_type, train.current_time
Outputs: train.output_dir
"""
output_dirs
=
[
f
"train_
{
current_time
}
"
]
if
model_name
:
save_dir
=
get_save_dir
(
model_name
,
finetuning_type
)
if
save_dir
and
os
.
path
.
isdir
(
save_dir
):
for
folder
in
os
.
listdir
(
save_dir
):
output_dir
=
os
.
path
.
join
(
save_dir
,
folder
)
if
os
.
path
.
isdir
(
output_dir
)
and
get_last_checkpoint
(
output_dir
)
is
not
None
:
output_dirs
.
append
(
folder
)
return
gr
.
Dropdown
(
choices
=
output_dirs
)
src/llamafactory/webui/css.py
0 → 100644
View file @
c7c477c7
# Copyright 2025 the LlamaFactory team.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file 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.
CSS
=
r
"""
.duplicate-button {
margin: auto !important;
color: white !important;
background: black !important;
border-radius: 100vh !important;
}
.thinking-summary {
padding: 8px !important;
}
.thinking-summary span {
border-radius: 4px !important;
padding: 4px !important;
cursor: pointer !important;
font-size: 14px !important;
background: rgb(245, 245, 245) !important;
}
.dark .thinking-summary span {
background: rgb(73, 73, 73) !important;
}
.thinking-container {
border-left: 2px solid #a6a6a6 !important;
padding-left: 10px !important;
margin: 4px 0 !important;
}
.thinking-container p {
color: #a6a6a6 !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;
}
"""
src/llamafactory/webui/engine.py
0 → 100644
View file @
c7c477c7
# Copyright 2025 the LlamaFactory team.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file 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.
from
typing
import
TYPE_CHECKING
,
Any
from
.chatter
import
WebChatModel
from
.common
import
create_ds_config
,
get_time
,
load_config
from
.locales
import
LOCALES
from
.manager
import
Manager
from
.runner
import
Runner
if
TYPE_CHECKING
:
from
gradio.components
import
Component
class
Engine
:
r
"""A general engine to control the behaviors of Web UI."""
def
__init__
(
self
,
demo_mode
:
bool
=
False
,
pure_chat
:
bool
=
False
)
->
None
:
self
.
demo_mode
=
demo_mode
self
.
pure_chat
=
pure_chat
self
.
manager
=
Manager
()
self
.
runner
=
Runner
(
self
.
manager
,
demo_mode
)
self
.
chatter
=
WebChatModel
(
self
.
manager
,
demo_mode
,
lazy_init
=
(
not
pure_chat
))
if
not
demo_mode
:
create_ds_config
()
def
_update_component
(
self
,
input_dict
:
dict
[
str
,
dict
[
str
,
Any
]])
->
dict
[
"Component"
,
"Component"
]:
r
"""Update gradio components according to the (elem_id, properties) mapping."""
output_dict
:
dict
[
Component
,
Component
]
=
{}
for
elem_id
,
elem_attr
in
input_dict
.
items
():
elem
=
self
.
manager
.
get_elem_by_id
(
elem_id
)
output_dict
[
elem
]
=
elem
.
__class__
(
**
elem_attr
)
return
output_dict
def
resume
(
self
):
r
"""Get the initial value of gradio components and restores training status if necessary."""
user_config
=
load_config
()
if
not
self
.
demo_mode
else
{}
# do not use config in demo mode
lang
=
user_config
.
get
(
"lang"
)
or
"en"
init_dict
=
{
"top.lang"
:
{
"value"
:
lang
},
"infer.chat_box"
:
{
"visible"
:
self
.
chatter
.
loaded
}}
if
not
self
.
pure_chat
:
current_time
=
get_time
()
hub_name
=
user_config
.
get
(
"hub_name"
)
or
"huggingface"
init_dict
[
"top.hub_name"
]
=
{
"value"
:
hub_name
}
init_dict
[
"train.current_time"
]
=
{
"value"
:
current_time
}
init_dict
[
"train.output_dir"
]
=
{
"value"
:
f
"train_
{
current_time
}
"
}
init_dict
[
"train.config_path"
]
=
{
"value"
:
f
"
{
current_time
}
.yaml"
}
init_dict
[
"eval.output_dir"
]
=
{
"value"
:
f
"eval_
{
current_time
}
"
}
init_dict
[
"infer.mm_box"
]
=
{
"visible"
:
False
}
if
user_config
.
get
(
"last_model"
,
None
):
init_dict
[
"top.model_name"
]
=
{
"value"
:
user_config
[
"last_model"
]}
yield
self
.
_update_component
(
init_dict
)
if
self
.
runner
.
running
and
not
self
.
demo_mode
and
not
self
.
pure_chat
:
yield
{
elem
:
elem
.
__class__
(
value
=
value
)
for
elem
,
value
in
self
.
runner
.
running_data
.
items
()}
if
self
.
runner
.
do_train
:
yield
self
.
_update_component
({
"train.resume_btn"
:
{
"value"
:
True
}})
else
:
yield
self
.
_update_component
({
"eval.resume_btn"
:
{
"value"
:
True
}})
def
change_lang
(
self
,
lang
:
str
):
r
"""Update the displayed language of gradio components."""
return
{
elem
:
elem
.
__class__
(
**
LOCALES
[
elem_name
][
lang
])
for
elem_name
,
elem
in
self
.
manager
.
get_elem_iter
()
if
elem_name
in
LOCALES
}
src/llamafactory/webui/interface.py
0 → 100644
View file @
c7c477c7
# Copyright 2025 the LlamaFactory team.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file 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.
import
os
import
platform
from
..extras.misc
import
fix_proxy
,
is_env_enabled
from
..extras.packages
import
is_gradio_available
from
.common
import
save_config
from
.components
import
(
create_chat_box
,
create_eval_tab
,
create_export_tab
,
create_footer
,
create_infer_tab
,
create_top
,
create_train_tab
,
)
from
.css
import
CSS
from
.engine
import
Engine
if
is_gradio_available
():
import
gradio
as
gr
def
create_ui
(
demo_mode
:
bool
=
False
)
->
"gr.Blocks"
:
engine
=
Engine
(
demo_mode
=
demo_mode
,
pure_chat
=
False
)
hostname
=
os
.
getenv
(
"HOSTNAME"
,
os
.
getenv
(
"COMPUTERNAME"
,
platform
.
node
())).
split
(
"."
)[
0
]
with
gr
.
Blocks
(
title
=
f
"LLaMA Factory (
{
hostname
}
)"
,
css
=
CSS
)
as
demo
:
title
=
gr
.
HTML
()
subtitle
=
gr
.
HTML
()
if
demo_mode
:
gr
.
DuplicateButton
(
value
=
"Duplicate Space for private use"
,
elem_classes
=
"duplicate-button"
)
engine
.
manager
.
add_elems
(
"head"
,
{
"title"
:
title
,
"subtitle"
:
subtitle
})
engine
.
manager
.
add_elems
(
"top"
,
create_top
())
lang
:
gr
.
Dropdown
=
engine
.
manager
.
get_elem_by_id
(
"top.lang"
)
with
gr
.
Tab
(
"Train"
):
engine
.
manager
.
add_elems
(
"train"
,
create_train_tab
(
engine
))
with
gr
.
Tab
(
"Evaluate & Predict"
):
engine
.
manager
.
add_elems
(
"eval"
,
create_eval_tab
(
engine
))
with
gr
.
Tab
(
"Chat"
):
engine
.
manager
.
add_elems
(
"infer"
,
create_infer_tab
(
engine
))
if
not
demo_mode
:
with
gr
.
Tab
(
"Export"
):
engine
.
manager
.
add_elems
(
"export"
,
create_export_tab
(
engine
))
engine
.
manager
.
add_elems
(
"footer"
,
create_footer
())
demo
.
load
(
engine
.
resume
,
outputs
=
engine
.
manager
.
get_elem_list
(),
concurrency_limit
=
None
)
lang
.
change
(
engine
.
change_lang
,
[
lang
],
engine
.
manager
.
get_elem_list
(),
queue
=
False
)
lang
.
input
(
save_config
,
inputs
=
[
lang
],
queue
=
False
)
return
demo
def
create_web_demo
()
->
"gr.Blocks"
:
engine
=
Engine
(
pure_chat
=
True
)
hostname
=
os
.
getenv
(
"HOSTNAME"
,
os
.
getenv
(
"COMPUTERNAME"
,
platform
.
node
())).
split
(
"."
)[
0
]
with
gr
.
Blocks
(
title
=
f
"LLaMA Factory Web Demo (
{
hostname
}
)"
,
css
=
CSS
)
as
demo
:
lang
=
gr
.
Dropdown
(
choices
=
[
"en"
,
"ru"
,
"zh"
,
"ko"
,
"ja"
],
scale
=
1
)
engine
.
manager
.
add_elems
(
"top"
,
dict
(
lang
=
lang
))
_
,
_
,
chat_elems
=
create_chat_box
(
engine
,
visible
=
True
)
engine
.
manager
.
add_elems
(
"infer"
,
chat_elems
)
demo
.
load
(
engine
.
resume
,
outputs
=
engine
.
manager
.
get_elem_list
(),
concurrency_limit
=
None
)
lang
.
change
(
engine
.
change_lang
,
[
lang
],
engine
.
manager
.
get_elem_list
(),
queue
=
False
)
lang
.
input
(
save_config
,
inputs
=
[
lang
],
queue
=
False
)
return
demo
def
run_web_ui
()
->
None
:
gradio_ipv6
=
is_env_enabled
(
"GRADIO_IPV6"
)
gradio_share
=
is_env_enabled
(
"GRADIO_SHARE"
)
server_name
=
os
.
getenv
(
"GRADIO_SERVER_NAME"
,
"[::]"
if
gradio_ipv6
else
"0.0.0.0"
)
print
(
"Visit http://ip:port for Web UI, e.g., http://127.0.0.1:7860"
)
fix_proxy
(
ipv6_enabled
=
gradio_ipv6
)
create_ui
().
queue
().
launch
(
share
=
gradio_share
,
server_name
=
server_name
,
inbrowser
=
True
)
def
run_web_demo
()
->
None
:
gradio_ipv6
=
is_env_enabled
(
"GRADIO_IPV6"
)
gradio_share
=
is_env_enabled
(
"GRADIO_SHARE"
)
server_name
=
os
.
getenv
(
"GRADIO_SERVER_NAME"
,
"[::]"
if
gradio_ipv6
else
"0.0.0.0"
)
print
(
"Visit http://ip:port for Web UI, e.g., http://127.0.0.1:7860"
)
fix_proxy
(
ipv6_enabled
=
gradio_ipv6
)
create_web_demo
().
queue
().
launch
(
share
=
gradio_share
,
server_name
=
server_name
,
inbrowser
=
True
)
src/llamafactory/webui/locales.py
0 → 100644
View file @
c7c477c7
# Copyright 2025 the LlamaFactory team.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file 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.
LOCALES
=
{
"title"
:
{
"en"
:
{
"value"
:
"<h1><center>🦙🏭LLaMA Factory: Unified Efficient Fine-Tuning of 100+ LLMs</center></h1>"
,
},
"ru"
:
{
"value"
:
"<h1><center>🦙🏭LLaMA Factory: Унифицированная эффективная тонкая настройка 100+ LLMs</center></h1>"
,
},
"zh"
:
{
"value"
:
"<h1><center>🦙🏭LLaMA Factory: 一站式大模型高效微调平台</center></h1>"
,
},
"ko"
:
{
"value"
:
"<h1><center>🦙🏭LLaMA Factory: 100+ LLMs를 위한 통합 효율적인 튜닝</center></h1>"
,
},
"ja"
:
{
"value"
:
"<h1><center>🦙🏭LLaMA Factory: 100+ LLMs の統合効率的なチューニング</center></h1>"
,
},
},
"subtitle"
:
{
"en"
:
{
"value"
:
(
"<h3><center>Visit <a href='https://github.com/hiyouga/LLaMA-Factory' target='_blank'>"
"GitHub Page</a></center></h3>"
),
},
"ru"
:
{
"value"
:
(
"<h3><center>Посетить <a href='https://github.com/hiyouga/LLaMA-Factory' target='_blank'>"
"страницу GitHub</a></center></h3>"
),
},
"zh"
:
{
"value"
:
(
"<h3><center>访问 <a href='https://github.com/hiyouga/LLaMA-Factory' target='_blank'>"
"GitHub 主页</a></center></h3>"
),
},
"ko"
:
{
"value"
:
(
"<h3><center><a href='https://github.com/hiyouga/LLaMA-Factory' target='_blank'>"
"GitHub 페이지</a>를 방문하세요.</center></h3>"
),
},
"ja"
:
{
"value"
:
(
"<h3><center><a href='https://github.com/hiyouga/LLaMA-Factory' target='_blank'>"
"GitHub ページ</a>にアクセスする</center></h3>"
),
},
},
"lang"
:
{
"en"
:
{
"label"
:
"Language"
,
},
"ru"
:
{
"label"
:
"Язык"
,
},
"zh"
:
{
"label"
:
"语言"
,
},
"ko"
:
{
"label"
:
"언어"
,
},
"ja"
:
{
"label"
:
"言語"
,
},
},
"model_name"
:
{
"en"
:
{
"label"
:
"Model name"
,
"info"
:
"Input the initial name to search for the model."
,
},
"ru"
:
{
"label"
:
"Название модели"
,
"info"
:
"Введите начальное имя для поиска модели."
,
},
"zh"
:
{
"label"
:
"模型名称"
,
"info"
:
"输入首单词以检索模型。"
,
},
"ko"
:
{
"label"
:
"모델 이름"
,
"info"
:
"모델을 검색할 초기 이름을 입력하세요."
,
},
"ja"
:
{
"label"
:
"モデル名"
,
"info"
:
"モデルを検索するための初期名を入力してください。"
,
},
},
"model_path"
:
{
"en"
:
{
"label"
:
"Model path"
,
"info"
:
"Path to pretrained model or model identifier from Hugging Face."
,
},
"ru"
:
{
"label"
:
"Путь к модели"
,
"info"
:
"Путь к предварительно обученной модели или идентификатор модели от Hugging Face."
,
},
"zh"
:
{
"label"
:
"模型路径"
,
"info"
:
"本地模型的文件路径或 Hugging Face 的模型标识符。"
,
},
"ko"
:
{
"label"
:
"모델 경로"
,
"info"
:
"사전 훈련된 모델의 경로 또는 Hugging Face의 모델 식별자."
,
},
"ja"
:
{
"label"
:
"モデルパス"
,
"info"
:
"事前学習済みモデルへのパス、または Hugging Face のモデル識別子。"
,
},
},
"hub_name"
:
{
"en"
:
{
"label"
:
"Hub name"
,
"info"
:
"Choose the model download source."
,
},
"ru"
:
{
"label"
:
"Имя хаба"
,
"info"
:
"Выберите источник загрузки модели."
,
},
"zh"
:
{
"label"
:
"模型下载源"
,
"info"
:
"选择模型下载源。(网络受限环境推荐使用 ModelScope)"
,
},
"ko"
:
{
"label"
:
"모델 다운로드 소스"
,
"info"
:
"모델 다운로드 소스를 선택하세요."
,
},
"ja"
:
{
"label"
:
"モデルダウンロードソース"
,
"info"
:
"モデルをダウンロードするためのソースを選択してください。"
,
},
},
"finetuning_type"
:
{
"en"
:
{
"label"
:
"Finetuning method"
,
},
"ru"
:
{
"label"
:
"Метод дообучения"
,
},
"zh"
:
{
"label"
:
"微调方法"
,
},
"ko"
:
{
"label"
:
"파인튜닝 방법"
,
},
"ja"
:
{
"label"
:
"ファインチューニング方法"
,
},
},
"checkpoint_path"
:
{
"en"
:
{
"label"
:
"Checkpoint path"
,
},
"ru"
:
{
"label"
:
"Путь контрольной точки"
,
},
"zh"
:
{
"label"
:
"检查点路径"
,
},
"ko"
:
{
"label"
:
"체크포인트 경로"
,
},
"ja"
:
{
"label"
:
"チェックポイントパス"
,
},
},
"quantization_bit"
:
{
"en"
:
{
"label"
:
"Quantization bit"
,
"info"
:
"Enable quantization (QLoRA)."
,
},
"ru"
:
{
"label"
:
"Уровень квантования"
,
"info"
:
"Включить квантование (QLoRA)."
,
},
"zh"
:
{
"label"
:
"量化等级"
,
"info"
:
"启用量化(QLoRA)。"
,
},
"ko"
:
{
"label"
:
"양자화 비트"
,
"info"
:
"양자화 활성화 (QLoRA)."
,
},
"ja"
:
{
"label"
:
"量子化ビット"
,
"info"
:
"量子化を有効にする (QLoRA)。"
,
},
},
"quantization_method"
:
{
"en"
:
{
"label"
:
"Quantization method"
,
"info"
:
"Quantization algorithm to use."
,
},
"ru"
:
{
"label"
:
"Метод квантования"
,
"info"
:
"Алгоритм квантования, который следует использовать."
,
},
"zh"
:
{
"label"
:
"量化方法"
,
"info"
:
"使用的量化算法。"
,
},
"ko"
:
{
"label"
:
"양자화 방법"
,
"info"
:
"사용할 양자화 알고리즘."
,
},
"ja"
:
{
"label"
:
"量子化方法"
,
"info"
:
"使用する量子化アルゴリズム。"
,
},
},
"template"
:
{
"en"
:
{
"label"
:
"Chat template"
,
"info"
:
"The chat template used in constructing prompts."
,
},
"ru"
:
{
"label"
:
"Шаблон чата"
,
"info"
:
"Шаблон чата используемый для составления подсказок."
,
},
"zh"
:
{
"label"
:
"对话模板"
,
"info"
:
"构建提示词时使用的模板。"
,
},
"ko"
:
{
"label"
:
"채팅 템플릿"
,
"info"
:
"프롬프트 작성에 사용되는 채팅 템플릿."
,
},
"ja"
:
{
"label"
:
"チャットテンプレート"
,
"info"
:
"プロンプトの構築に使用されるチャットテンプレート。"
,
},
},
"rope_scaling"
:
{
"en"
:
{
"label"
:
"RoPE scaling"
,
"info"
:
"RoPE scaling method to use."
,
},
"ru"
:
{
"label"
:
"Масштабирование RoPE"
,
"info"
:
"Метод масштабирования RoPE для использования."
,
},
"zh"
:
{
"label"
:
"RoPE 插值方法"
,
"info"
:
"RoPE 插值时使用的方法。"
},
"ko"
:
{
"label"
:
"RoPE 스케일링"
,
"info"
:
"사용할 RoPE 스케일링 방법."
,
},
"ja"
:
{
"label"
:
"RoPE スケーリング"
,
"info"
:
"使用する RoPE スケーリング方法。"
,
},
},
"booster"
:
{
"en"
:
{
"label"
:
"Booster"
,
"info"
:
"Approach used to boost training speed."
,
},
"ru"
:
{
"label"
:
"Ускоритель"
,
"info"
:
"Подход, используемый для ускорения обучения."
,
},
"zh"
:
{
"label"
:
"加速方式"
,
"info"
:
"使用的加速方法。"
},
"ko"
:
{
"label"
:
"부스터"
,
"info"
:
"훈련 속도를 향상시키기 위해 사용된 접근 방식."
,
},
"ja"
:
{
"label"
:
"ブースター"
,
"info"
:
"トレーニング速度を向上させるためのアプローチ。"
,
},
},
"training_stage"
:
{
"en"
:
{
"label"
:
"Stage"
,
"info"
:
"The stage to perform in training."
,
},
"ru"
:
{
"label"
:
"Этап"
,
"info"
:
"Этап выполнения обучения."
,
},
"zh"
:
{
"label"
:
"训练阶段"
,
"info"
:
"目前采用的训练方式。"
,
},
"ko"
:
{
"label"
:
"학습 단계"
,
"info"
:
"수행할 학습 방법."
,
},
"ja"
:
{
"label"
:
"ステージ"
,
"info"
:
"トレーニングで実行するステージ。"
,
},
},
"dataset_dir"
:
{
"en"
:
{
"label"
:
"Data dir"
,
"info"
:
"Path to the data directory."
,
},
"ru"
:
{
"label"
:
"Директория данных"
,
"info"
:
"Путь к директории данных."
,
},
"zh"
:
{
"label"
:
"数据路径"
,
"info"
:
"数据文件夹的路径。"
,
},
"ko"
:
{
"label"
:
"데이터 디렉토리"
,
"info"
:
"데이터 디렉토리의 경로."
,
},
"ja"
:
{
"label"
:
"データディレクトリ"
,
"info"
:
"データディレクトリへのパス。"
,
},
},
"dataset"
:
{
"en"
:
{
"label"
:
"Dataset"
,
},
"ru"
:
{
"label"
:
"Набор данных"
,
},
"zh"
:
{
"label"
:
"数据集"
,
},
"ko"
:
{
"label"
:
"데이터셋"
,
},
"ja"
:
{
"label"
:
"データセット"
,
},
},
"data_preview_btn"
:
{
"en"
:
{
"value"
:
"Preview dataset"
,
},
"ru"
:
{
"value"
:
"Просмотреть набор данных"
,
},
"zh"
:
{
"value"
:
"预览数据集"
,
},
"ko"
:
{
"value"
:
"데이터셋 미리보기"
,
},
"ja"
:
{
"value"
:
"データセットをプレビュー"
,
},
},
"preview_count"
:
{
"en"
:
{
"label"
:
"Count"
,
},
"ru"
:
{
"label"
:
"Количество"
,
},
"zh"
:
{
"label"
:
"数量"
,
},
"ko"
:
{
"label"
:
"개수"
,
},
"ja"
:
{
"label"
:
"カウント"
,
},
},
"page_index"
:
{
"en"
:
{
"label"
:
"Page"
,
},
"ru"
:
{
"label"
:
"Страница"
,
},
"zh"
:
{
"label"
:
"页数"
,
},
"ko"
:
{
"label"
:
"페이지"
,
},
"ja"
:
{
"label"
:
"ページ"
,
},
},
"prev_btn"
:
{
"en"
:
{
"value"
:
"Prev"
,
},
"ru"
:
{
"value"
:
"Предыдущая"
,
},
"zh"
:
{
"value"
:
"上一页"
,
},
"ko"
:
{
"value"
:
"이전"
,
},
"ja"
:
{
"value"
:
"前へ"
,
},
},
"next_btn"
:
{
"en"
:
{
"value"
:
"Next"
,
},
"ru"
:
{
"value"
:
"Следующая"
,
},
"zh"
:
{
"value"
:
"下一页"
,
},
"ko"
:
{
"value"
:
"다음"
,
},
"ja"
:
{
"value"
:
"次へ"
,
},
},
"close_btn"
:
{
"en"
:
{
"value"
:
"Close"
,
},
"ru"
:
{
"value"
:
"Закрыть"
,
},
"zh"
:
{
"value"
:
"关闭"
,
},
"ko"
:
{
"value"
:
"닫기"
,
},
"ja"
:
{
"value"
:
"閉じる"
,
},
},
"preview_samples"
:
{
"en"
:
{
"label"
:
"Samples"
,
},
"ru"
:
{
"label"
:
"Примеры"
,
},
"zh"
:
{
"label"
:
"样例"
,
},
"ko"
:
{
"label"
:
"샘플"
,
},
"ja"
:
{
"label"
:
"サンプル"
,
},
},
"learning_rate"
:
{
"en"
:
{
"label"
:
"Learning rate"
,
"info"
:
"Initial learning rate for AdamW."
,
},
"ru"
:
{
"label"
:
"Скорость обучения"
,
"info"
:
"Начальная скорость обучения для AdamW."
,
},
"zh"
:
{
"label"
:
"学习率"
,
"info"
:
"AdamW 优化器的初始学习率。"
,
},
"ko"
:
{
"label"
:
"학습률"
,
"info"
:
"AdamW의 초기 학습률."
,
},
"ja"
:
{
"label"
:
"学習率"
,
"info"
:
"AdamW の初期学習率。"
,
},
},
"num_train_epochs"
:
{
"en"
:
{
"label"
:
"Epochs"
,
"info"
:
"Total number of training epochs to perform."
,
},
"ru"
:
{
"label"
:
"Эпохи"
,
"info"
:
"Общее количество эпох обучения."
,
},
"zh"
:
{
"label"
:
"训练轮数"
,
"info"
:
"需要执行的训练总轮数。"
,
},
"ko"
:
{
"label"
:
"에포크"
,
"info"
:
"수행할 총 학습 에포크 수."
,
},
"ja"
:
{
"label"
:
"エポック数"
,
"info"
:
"実行するトレーニングの総エポック数。"
,
},
},
"max_grad_norm"
:
{
"en"
:
{
"label"
:
"Maximum gradient norm"
,
"info"
:
"Norm for gradient clipping."
,
},
"ru"
:
{
"label"
:
"Максимальная норма градиента"
,
"info"
:
"Норма для обрезки градиента."
,
},
"zh"
:
{
"label"
:
"最大梯度范数"
,
"info"
:
"用于梯度裁剪的范数。"
,
},
"ko"
:
{
"label"
:
"최대 그레디언트 노름(norm)"
,
"info"
:
"그레디언트 클리핑을 위한 노름(norm)."
,
},
"ja"
:
{
"label"
:
"最大勾配ノルム"
,
"info"
:
"勾配クリッピングのためのノルム。"
,
},
},
"max_samples"
:
{
"en"
:
{
"label"
:
"Max samples"
,
"info"
:
"Maximum samples per dataset."
,
},
"ru"
:
{
"label"
:
"Максимальное количество образцов"
,
"info"
:
"Максимальное количество образцов на набор данных."
,
},
"zh"
:
{
"label"
:
"最大样本数"
,
"info"
:
"每个数据集的最大样本数。"
,
},
"ko"
:
{
"label"
:
"최대 샘플 수"
,
"info"
:
"데이터셋 당 최대 샘플 수."
,
},
"ja"
:
{
"label"
:
"最大サンプル数"
,
"info"
:
"データセットごとの最大サンプル数。"
,
},
},
"compute_type"
:
{
"en"
:
{
"label"
:
"Compute type"
,
"info"
:
"Whether to use mixed precision training."
,
},
"ru"
:
{
"label"
:
"Тип вычислений"
,
"info"
:
"Использовать ли обучение смешанной точности."
,
},
"zh"
:
{
"label"
:
"计算类型"
,
"info"
:
"是否使用混合精度训练。"
,
},
"ko"
:
{
"label"
:
"연산 유형"
,
"info"
:
"혼합 정밀도 훈련을 사용할지 여부."
,
},
"ja"
:
{
"label"
:
"計算タイプ"
,
"info"
:
"混合精度トレーニングを使用するかどうか。"
,
},
},
"cutoff_len"
:
{
"en"
:
{
"label"
:
"Cutoff length"
,
"info"
:
"Max tokens in input sequence."
,
},
"ru"
:
{
"label"
:
"Длина обрезки"
,
"info"
:
"Максимальное количество токенов во входной последовательности."
,
},
"zh"
:
{
"label"
:
"截断长度"
,
"info"
:
"输入序列分词后的最大长度。"
,
},
"ko"
:
{
"label"
:
"컷오프 길이"
,
"info"
:
"입력 시퀀스의 최대 토큰 수."
,
},
"ja"
:
{
"label"
:
"カットオフ長"
,
"info"
:
"入力シーケンスの最大トークン数。"
,
},
},
"batch_size"
:
{
"en"
:
{
"label"
:
"Batch size"
,
"info"
:
"Number of samples processed on each GPU."
,
},
"ru"
:
{
"label"
:
"Размер пакета"
,
"info"
:
"Количество образцов для обработки на каждом GPU."
,
},
"zh"
:
{
"label"
:
"批处理大小"
,
"info"
:
"每个 GPU 处理的样本数量。"
,
},
"ko"
:
{
"label"
:
"배치 크기"
,
"info"
:
"각 GPU에서 처리되는 샘플 수."
,
},
"ja"
:
{
"label"
:
"バッチサイズ"
,
"info"
:
"各 GPU で処理されるサンプル数。"
,
},
},
"gradient_accumulation_steps"
:
{
"en"
:
{
"label"
:
"Gradient accumulation"
,
"info"
:
"Number of steps for gradient accumulation."
,
},
"ru"
:
{
"label"
:
"Накопление градиента"
,
"info"
:
"Количество шагов накопления градиента."
,
},
"zh"
:
{
"label"
:
"梯度累积"
,
"info"
:
"梯度累积的步数。"
,
},
"ko"
:
{
"label"
:
"그레디언트 누적"
,
"info"
:
"그레디언트 누적 단계 수."
,
},
"ja"
:
{
"label"
:
"勾配累積"
,
"info"
:
"勾配累積のステップ数。"
,
},
},
"val_size"
:
{
"en"
:
{
"label"
:
"Val size"
,
"info"
:
"Percentage of validation set from the entire dataset."
,
},
"ru"
:
{
"label"
:
"Размер валидации"
,
"info"
:
"Пропорция данных в наборе для разработки."
,
},
"zh"
:
{
"label"
:
"验证集比例"
,
"info"
:
"验证集占全部样本的百分比。"
,
},
"ko"
:
{
"label"
:
"검증 데이터셋 크기"
,
"info"
:
"개발 데이터셋에서 검증 데이터의 비율."
,
},
"ja"
:
{
"label"
:
"検証セットサイズ"
,
"info"
:
"データセット全体に対する検証セットの割合。"
,
},
},
"lr_scheduler_type"
:
{
"en"
:
{
"label"
:
"LR scheduler"
,
"info"
:
"Name of the learning rate scheduler."
,
},
"ru"
:
{
"label"
:
"Планировщик скорости обучения"
,
"info"
:
"Название планировщика скорости обучения."
,
},
"zh"
:
{
"label"
:
"学习率调节器"
,
"info"
:
"学习率调度器的名称。"
,
},
"ko"
:
{
"label"
:
"LR 스케줄러"
,
"info"
:
"학습률 스케줄러의 이름."
,
},
"ja"
:
{
"label"
:
"学習率スケジューラ"
,
"info"
:
"学習率スケジューラの名前。"
,
},
},
"extra_tab"
:
{
"en"
:
{
"label"
:
"Extra configurations"
,
},
"ru"
:
{
"label"
:
"Дополнительные конфигурации"
,
},
"zh"
:
{
"label"
:
"其它参数设置"
,
},
"ko"
:
{
"label"
:
"추가 구성(configuration)"
,
},
"ja"
:
{
"label"
:
"追加設定"
,
},
},
"logging_steps"
:
{
"en"
:
{
"label"
:
"Logging steps"
,
"info"
:
"Number of steps between two logs."
,
},
"ru"
:
{
"label"
:
"Шаги логирования"
,
"info"
:
"Количество шагов между двумя записями в журнале."
,
},
"zh"
:
{
"label"
:
"日志间隔"
,
"info"
:
"每两次日志输出间的更新步数。"
,
},
"ko"
:
{
"label"
:
"로깅 스텝"
,
"info"
:
"이전 로깅과 다음 로깅 간 스텝 수."
,
},
"ja"
:
{
"label"
:
"ロギングステップ"
,
"info"
:
"2 つのログ間のステップ数。"
,
},
},
"save_steps"
:
{
"en"
:
{
"label"
:
"Save steps"
,
"info"
:
"Number of steps between two checkpoints."
,
},
"ru"
:
{
"label"
:
"Шаги сохранения"
,
"info"
:
"Количество шагов между двумя контрольными точками."
,
},
"zh"
:
{
"label"
:
"保存间隔"
,
"info"
:
"每两次断点保存间的更新步数。"
,
},
"ko"
:
{
"label"
:
"저장 스텝"
,
"info"
:
"이전 체크포인트와 다음 체크포인트 사이의 스텝 수."
,
},
"ja"
:
{
"label"
:
"保存ステップ"
,
"info"
:
"2 つのチェックポイント間のステップ数。"
,
},
},
"warmup_steps"
:
{
"en"
:
{
"label"
:
"Warmup steps"
,
"info"
:
"Number of steps used for warmup."
,
},
"ru"
:
{
"label"
:
"Шаги прогрева"
,
"info"
:
"Количество шагов, используемых для прогрева."
,
},
"zh"
:
{
"label"
:
"预热步数"
,
"info"
:
"学习率预热采用的步数。"
,
},
"ko"
:
{
"label"
:
"Warmup 스텝"
,
"info"
:
"Warmup에 사용되는 스텝 수."
,
},
"ja"
:
{
"label"
:
"ウォームアップステップ"
,
"info"
:
"ウォームアップに使用されるステップ数。"
,
},
},
"neftune_alpha"
:
{
"en"
:
{
"label"
:
"NEFTune alpha"
,
"info"
:
"Magnitude of noise adding to embedding vectors."
,
},
"ru"
:
{
"label"
:
"NEFTune alpha"
,
"info"
:
"Величина шума, добавляемого к векторам вложений."
,
},
"zh"
:
{
"label"
:
"NEFTune 噪声参数"
,
"info"
:
"嵌入向量所添加的噪声大小。"
,
},
"ko"
:
{
"label"
:
"NEFTune 알파"
,
"info"
:
"임베딩 벡터에 추가되는 노이즈의 크기."
,
},
"ja"
:
{
"label"
:
"NEFTune alpha"
,
"info"
:
"埋め込みベクトルに追加されるノイズの大きさ。"
,
},
},
"extra_args"
:
{
"en"
:
{
"label"
:
"Extra arguments"
,
"info"
:
"Extra arguments passed to the trainer in JSON format."
,
},
"ru"
:
{
"label"
:
"Дополнительные аргументы"
,
"info"
:
"Дополнительные аргументы, которые передаются тренеру в формате JSON."
,
},
"zh"
:
{
"label"
:
"额外参数"
,
"info"
:
"以 JSON 格式传递给训练器的额外参数。"
,
},
"ko"
:
{
"label"
:
"추가 인수"
,
"info"
:
"JSON 형식으로 트레이너에게 전달할 추가 인수입니다."
,
},
"ja"
:
{
"label"
:
"追加引数"
,
"info"
:
"JSON 形式でトレーナーに渡される追加引数。"
,
},
},
"packing"
:
{
"en"
:
{
"label"
:
"Pack sequences"
,
"info"
:
"Pack sequences into samples of fixed length."
,
},
"ru"
:
{
"label"
:
"Упаковка последовательностей"
,
"info"
:
"Упаковка последовательностей в образцы фиксированной длины."
,
},
"zh"
:
{
"label"
:
"序列打包"
,
"info"
:
"将序列打包为等长样本。"
,
},
"ko"
:
{
"label"
:
"시퀀스 패킹"
,
"info"
:
"고정된 길이의 샘플로 시퀀스를 패킹합니다."
,
},
"ja"
:
{
"label"
:
"シーケンスパッキング"
,
"info"
:
"シーケンスを固定長のサンプルにパッキングします。"
,
},
},
"neat_packing"
:
{
"en"
:
{
"label"
:
"Use neat packing"
,
"info"
:
"Avoid cross-attention between packed sequences."
,
},
"ru"
:
{
"label"
:
"Используйте аккуратную упаковку"
,
"info"
:
"избегайте перекрестного внимания между упакованными последовательностями."
,
},
"zh"
:
{
"label"
:
"使用无污染打包"
,
"info"
:
"避免打包后的序列产生交叉注意力。"
,
},
"ko"
:
{
"label"
:
"니트 패킹 사용"
,
"info"
:
"패킹된 시퀀스 간의 크로스 어텐션을 피합니다."
,
},
"ja"
:
{
"label"
:
"無汚染パッキングを使用"
,
"info"
:
"パッキング後のシーケンス間のクロスアテンションを避けます。"
,
},
},
"train_on_prompt"
:
{
"en"
:
{
"label"
:
"Train on prompt"
,
"info"
:
"Disable the label mask on the prompt (only for SFT)."
,
},
"ru"
:
{
"label"
:
"Тренировка на подсказке"
,
"info"
:
"Отключить маску меток на подсказке (только для SFT)."
,
},
"zh"
:
{
"label"
:
"学习提示词"
,
"info"
:
"不在提示词的部分添加掩码(仅适用于 SFT)。"
,
},
"ko"
:
{
"label"
:
"프롬프트도 학습"
,
"info"
:
"프롬프트에서 라벨 마스킹을 비활성화합니다 (SFT에만 해당)."
,
},
"ja"
:
{
"label"
:
"プロンプトで学習"
,
"info"
:
"プロンプト部分にマスクを追加しない(SFT のみ)。"
,
},
},
"mask_history"
:
{
"en"
:
{
"label"
:
"Mask history"
,
"info"
:
"Train on the last turn only (only for SFT)."
,
},
"ru"
:
{
"label"
:
"История масок"
,
"info"
:
"Тренироваться только на последнем шаге (только для SFT)."
,
},
"zh"
:
{
"label"
:
"不学习历史对话"
,
"info"
:
"仅学习最后一轮对话(仅适用于 SFT)。"
,
},
"ko"
:
{
"label"
:
"히스토리 마스킹"
,
"info"
:
"대화 데이터의 마지막 턴만 학습합니다 (SFT에만 해당)."
,
},
"ja"
:
{
"label"
:
"履歴をマスク"
,
"info"
:
"最後のターンのみを学習する(SFT のみ)。"
,
},
},
"resize_vocab"
:
{
"en"
:
{
"label"
:
"Resize token embeddings"
,
"info"
:
"Resize the tokenizer vocab and the embedding layers."
,
},
"ru"
:
{
"label"
:
"Изменение размера токенных эмбеддингов"
,
"info"
:
"Изменить размер словаря токенизатора и слоев эмбеддинга."
,
},
"zh"
:
{
"label"
:
"更改词表大小"
,
"info"
:
"更改分词器词表和嵌入层的大小。"
,
},
"ko"
:
{
"label"
:
"토큰 임베딩의 사이즈 조정"
,
"info"
:
"토크나이저 어휘와 임베딩 레이어의 크기를 조정합니다."
,
},
"ja"
:
{
"label"
:
"トークン埋め込みのサイズ変更"
,
"info"
:
"トークナイザーの語彙と埋め込み層のサイズを変更します。"
,
},
},
"use_llama_pro"
:
{
"en"
:
{
"label"
:
"Enable LLaMA Pro"
,
"info"
:
"Make the parameters in the expanded blocks trainable."
,
},
"ru"
:
{
"label"
:
"Включить LLaMA Pro"
,
"info"
:
"Сделать параметры в расширенных блоках обучаемыми."
,
},
"zh"
:
{
"label"
:
"使用 LLaMA Pro"
,
"info"
:
"仅训练块扩展后的参数。"
,
},
"ko"
:
{
"label"
:
"LLaMA Pro 사용"
,
"info"
:
"확장된 블록의 매개변수를 학습 가능하게 만듭니다."
,
},
"ja"
:
{
"label"
:
"LLaMA Pro を有効化"
,
"info"
:
"拡張ブロックのパラメータのみをトレーニングします。"
,
},
},
"enable_thinking"
:
{
"en"
:
{
"label"
:
"Enable thinking"
,
"info"
:
"Whether or not to enable thinking mode for reasoning models."
,
},
"ru"
:
{
"label"
:
"Включить мысли"
,
"info"
:
"Включить режим мысли для моделей решающего характера."
,
},
"zh"
:
{
"label"
:
"启用思考模式"
,
"info"
:
"是否启用推理模型的思考模式。"
,
},
"ko"
:
{
"label"
:
"생각 모드 활성화"
,
"info"
:
"추론 모델의 생각 모드를 활성화할지 여부."
,
},
"ja"
:
{
"label"
:
"思考モードを有効化"
,
"info"
:
"推論モデルの思考モードを有効にするかどうか。"
,
},
},
"report_to"
:
{
"en"
:
{
"label"
:
"Enable external logger"
,
"info"
:
"Use TensorBoard or wandb to log experiment."
,
},
"ru"
:
{
"label"
:
"Включить внешний регистратор"
,
"info"
:
"Использовать TensorBoard или wandb для ведения журнала экспериментов."
,
},
"zh"
:
{
"label"
:
"启用外部记录面板"
,
"info"
:
"使用 TensorBoard 或 wandb 记录实验。"
,
},
"ko"
:
{
"label"
:
"외부 logger 활성화"
,
"info"
:
"TensorBoard 또는 wandb를 사용하여 실험을 기록합니다."
,
},
"ja"
:
{
"label"
:
"外部ロガーを有効化"
,
"info"
:
"TensorBoard または wandb を使用して実験を記録します。"
,
},
},
"freeze_tab"
:
{
"en"
:
{
"label"
:
"Freeze tuning configurations"
,
},
"ru"
:
{
"label"
:
"конфигурации для настройки заморозки"
,
},
"zh"
:
{
"label"
:
"部分参数微调设置"
,
},
"ko"
:
{
"label"
:
"Freeze tuning 설정"
,
},
"ja"
:
{
"label"
:
"フリーズチューニング設定"
,
},
},
"freeze_trainable_layers"
:
{
"en"
:
{
"label"
:
"Trainable layers"
,
"info"
:
"Number of the last(+)/first(-) hidden layers to be set as trainable."
,
},
"ru"
:
{
"label"
:
"Обучаемые слои"
,
"info"
:
"Количество последних (+)/первых (-) скрытых слоев, которые будут установлены как обучаемые."
,
},
"zh"
:
{
"label"
:
"可训练层数"
,
"info"
:
"最末尾(+)/最前端(-)可训练隐藏层的数量。"
,
},
"ko"
:
{
"label"
:
"학습 가능한 레이어"
,
"info"
:
"학습 가능하게 설정할 마지막(+)/처음(-) 히든 레이어의 수."
,
},
"ja"
:
{
"label"
:
"学習可能なレイヤー"
,
"info"
:
"最後(+)/最初(-)の学習可能な隠れ層の数。"
,
},
},
"freeze_trainable_modules"
:
{
"en"
:
{
"label"
:
"Trainable modules"
,
"info"
:
"Name(s) of trainable modules. Use commas to separate multiple modules."
,
},
"ru"
:
{
"label"
:
"Обучаемые модули"
,
"info"
:
"Название обучаемых модулей. Используйте запятые для разделения нескольких модулей."
,
},
"zh"
:
{
"label"
:
"可训练模块"
,
"info"
:
"可训练模块的名称。使用英文逗号分隔多个名称。"
,
},
"ko"
:
{
"label"
:
"학습 가능한 모듈"
,
"info"
:
"학습 가능한 모듈의 이름. 여러 모듈을 구분하려면 쉼표(,)를 사용하세요."
,
},
"ja"
:
{
"label"
:
"学習可能なモジュール"
,
"info"
:
"学習可能なモジュールの名前。複数のモジュールを区切るにはカンマを使用します。"
,
},
},
"freeze_extra_modules"
:
{
"en"
:
{
"label"
:
"Extra modules (optional)"
,
"info"
:
(
"Name(s) of modules apart from hidden layers to be set as trainable. "
"Use commas to separate multiple modules."
),
},
"ru"
:
{
"label"
:
"Дополнительные модули (опционально)"
,
"info"
:
(
"Имена модулей, кроме скрытых слоев, которые следует установить в качестве обучаемых. "
"Используйте запятые для разделения нескольких модулей."
),
},
"zh"
:
{
"label"
:
"额外模块(非必填)"
,
"info"
:
"除隐藏层以外的可训练模块名称。使用英文逗号分隔多个名称。"
,
},
"ko"
:
{
"label"
:
"추가 모듈 (선택 사항)"
,
"info"
:
"히든 레이어 외에 학습 가능하게 설정할 모듈의 이름. 모듈 간에는 쉼표(,)로 구분하십시오."
,
},
"ja"
:
{
"label"
:
"追加モジュール(オプション)"
,
"info"
:
"隠れ層以外の学習可能なモジュールの名前。複数のモジュールを区切るにはカンマを使用します。"
,
},
},
"lora_tab"
:
{
"en"
:
{
"label"
:
"LoRA configurations"
,
},
"ru"
:
{
"label"
:
"Конфигурации LoRA"
,
},
"zh"
:
{
"label"
:
"LoRA 参数设置"
,
},
"ko"
:
{
"label"
:
"LoRA 구성"
,
},
"ja"
:
{
"label"
:
"LoRA 設定"
,
},
},
"lora_rank"
:
{
"en"
:
{
"label"
:
"LoRA rank"
,
"info"
:
"The rank of LoRA matrices."
,
},
"ru"
:
{
"label"
:
"Ранг матриц LoRA"
,
"info"
:
"Ранг матриц LoRA."
,
},
"zh"
:
{
"label"
:
"LoRA 秩"
,
"info"
:
"LoRA 矩阵的秩大小。"
,
},
"ko"
:
{
"label"
:
"LoRA 랭크"
,
"info"
:
"LoRA 행렬의 랭크."
,
},
"ja"
:
{
"label"
:
"LoRA ランク"
,
"info"
:
"LoRA 行列のランク。"
,
},
},
"lora_alpha"
:
{
"en"
:
{
"label"
:
"LoRA alpha"
,
"info"
:
"Lora scaling coefficient."
,
},
"ru"
:
{
"label"
:
"LoRA alpha"
,
"info"
:
"Коэффициент масштабирования LoRA."
,
},
"zh"
:
{
"label"
:
"LoRA 缩放系数"
,
"info"
:
"LoRA 缩放系数大小。"
,
},
"ko"
:
{
"label"
:
"LoRA 알파"
,
"info"
:
"LoRA 스케일링 계수."
,
},
"ja"
:
{
"label"
:
"LoRA alpha"
,
"info"
:
"LoRA スケーリング係数。"
,
},
},
"lora_dropout"
:
{
"en"
:
{
"label"
:
"LoRA dropout"
,
"info"
:
"Dropout ratio of LoRA weights."
,
},
"ru"
:
{
"label"
:
"Вероятность отсева LoRA"
,
"info"
:
"Вероятность отсева весов LoRA."
,
},
"zh"
:
{
"label"
:
"LoRA 随机丢弃"
,
"info"
:
"LoRA 权重随机丢弃的概率。"
,
},
"ko"
:
{
"label"
:
"LoRA 드롭아웃"
,
"info"
:
"LoRA 가중치의 드롭아웃 비율."
,
},
"ja"
:
{
"label"
:
"LoRA ドロップアウト"
,
"info"
:
"LoRA 重みのドロップアウト確率。"
,
},
},
"loraplus_lr_ratio"
:
{
"en"
:
{
"label"
:
"LoRA+ LR ratio"
,
"info"
:
"The LR ratio of the B matrices in LoRA."
,
},
"ru"
:
{
"label"
:
"LoRA+ LR коэффициент"
,
"info"
:
"Коэффициент LR матриц B в LoRA."
,
},
"zh"
:
{
"label"
:
"LoRA+ 学习率比例"
,
"info"
:
"LoRA+ 中 B 矩阵的学习率倍数。"
,
},
"ko"
:
{
"label"
:
"LoRA+ LR 비율"
,
"info"
:
"LoRA에서 B 행렬의 LR 비율."
,
},
"ja"
:
{
"label"
:
"LoRA+ LR 比率"
,
"info"
:
"LoRA+ の B 行列の学習率倍率。"
,
},
},
"create_new_adapter"
:
{
"en"
:
{
"label"
:
"Create new adapter"
,
"info"
:
"Create a new adapter with randomly initialized weight upon the existing one."
,
},
"ru"
:
{
"label"
:
"Создать новый адаптер"
,
"info"
:
"Создать новый адаптер с случайной инициализацией веса на основе существующего."
,
},
"zh"
:
{
"label"
:
"新建适配器"
,
"info"
:
"在现有的适配器上创建一个随机初始化后的新适配器。"
,
},
"ko"
:
{
"label"
:
"새 어댑터 생성"
,
"info"
:
"기존 어댑터 위에 무작위로 초기화된 가중치를 가진 새 어댑터를 생성합니다."
,
},
"ja"
:
{
"label"
:
"新しいアダプターを作成"
,
"info"
:
"既存のアダプター上にランダムに初期化された新しいアダプターを作成します。"
,
},
},
"use_rslora"
:
{
"en"
:
{
"label"
:
"Use rslora"
,
"info"
:
"Use the rank stabilization scaling factor for LoRA layer."
,
},
"ru"
:
{
"label"
:
"Использовать rslora"
,
"info"
:
"Использовать коэффициент масштабирования стабилизации ранга для слоя LoRA."
,
},
"zh"
:
{
"label"
:
"使用 rslora"
,
"info"
:
"对 LoRA 层使用秩稳定缩放方法。"
,
},
"ko"
:
{
"label"
:
"rslora 사용"
,
"info"
:
"LoRA 레이어에 랭크 안정화 스케일링 계수를 사용합니다."
,
},
"ja"
:
{
"label"
:
"rslora を使用"
,
"info"
:
"LoRA 層にランク安定化スケーリング方法を使用します。"
,
},
},
"use_dora"
:
{
"en"
:
{
"label"
:
"Use DoRA"
,
"info"
:
"Use weight-decomposed LoRA."
,
},
"ru"
:
{
"label"
:
"Используйте DoRA"
,
"info"
:
"Используйте LoRA с декомпозицией весов."
,
},
"zh"
:
{
"label"
:
"使用 DoRA"
,
"info"
:
"使用权重分解的 LoRA。"
,
},
"ko"
:
{
"label"
:
"DoRA 사용"
,
"info"
:
"가중치-분해 LoRA를 사용합니다."
,
},
"ja"
:
{
"label"
:
"DoRA を使用"
,
"info"
:
"重み分解された LoRA を使用します。"
,
},
},
"use_pissa"
:
{
"en"
:
{
"label"
:
"Use PiSSA"
,
"info"
:
"Use PiSSA method."
,
},
"ru"
:
{
"label"
:
"используйте PiSSA"
,
"info"
:
"Используйте метод PiSSA."
,
},
"zh"
:
{
"label"
:
"使用 PiSSA"
,
"info"
:
"使用 PiSSA 方法。"
,
},
"ko"
:
{
"label"
:
"PiSSA 사용"
,
"info"
:
"PiSSA 방법을 사용합니다."
,
},
"ja"
:
{
"label"
:
"PiSSA を使用"
,
"info"
:
"PiSSA メソッドを使用します。"
,
},
},
"lora_target"
:
{
"en"
:
{
"label"
:
"LoRA modules (optional)"
,
"info"
:
"Name(s) of modules to apply LoRA. Use commas to separate multiple modules."
,
},
"ru"
:
{
"label"
:
"Модули LoRA (опционально)"
,
"info"
:
"Имена модулей для применения LoRA. Используйте запятые для разделения нескольких модулей."
,
},
"zh"
:
{
"label"
:
"LoRA 作用模块(非必填)"
,
"info"
:
"应用 LoRA 的模块名称。使用英文逗号分隔多个名称。"
,
},
"ko"
:
{
"label"
:
"LoRA 모듈 (선택 사항)"
,
"info"
:
"LoRA를 적용할 모듈의 이름. 모듈 간에는 쉼표(,)로 구분하십시오."
,
},
"ja"
:
{
"label"
:
"LoRA モジュール(オプション)"
,
"info"
:
"LoRA を適用するモジュールの名前。複数のモジュールを区切るにはカンマを使用します。"
,
},
},
"additional_target"
:
{
"en"
:
{
"label"
:
"Additional modules (optional)"
,
"info"
:
(
"Name(s) of modules apart from LoRA layers to be set as trainable. "
"Use commas to separate multiple modules."
),
},
"ru"
:
{
"label"
:
"Дополнительные модули (опционально)"
,
"info"
:
(
"Имена модулей, кроме слоев LoRA, которые следует установить в качестве обучаемых. "
"Используйте запятые для разделения нескольких модулей."
),
},
"zh"
:
{
"label"
:
"附加模块(非必填)"
,
"info"
:
"除 LoRA 层以外的可训练模块名称。使用英文逗号分隔多个名称。"
,
},
"ko"
:
{
"label"
:
"추가 모듈 (선택 사항)"
,
"info"
:
"LoRA 레이어 외에 학습 가능하게 설정할 모듈의 이름. 모듈 간에는 쉼표(,)로 구분하십시오."
,
},
"ja"
:
{
"label"
:
"追加モジュール(オプション)"
,
"info"
:
"LoRA 層以外の学習可能なモジュールの名前。複数のモジュールを区切るにはカンマを使用します。"
,
},
},
"rlhf_tab"
:
{
"en"
:
{
"label"
:
"RLHF configurations"
,
},
"ru"
:
{
"label"
:
"Конфигурации RLHF"
,
},
"zh"
:
{
"label"
:
"RLHF 参数设置"
,
},
"ko"
:
{
"label"
:
"RLHF 구성"
,
},
"ja"
:
{
"label"
:
"RLHF 設定"
,
},
},
"pref_beta"
:
{
"en"
:
{
"label"
:
"Beta value"
,
"info"
:
"Value of the beta parameter in the loss."
,
},
"ru"
:
{
"label"
:
"Бета значение"
,
"info"
:
"Значение параметра бета в функции потерь."
,
},
"zh"
:
{
"label"
:
"Beta 参数"
,
"info"
:
"损失函数中 beta 超参数大小。"
,
},
"ko"
:
{
"label"
:
"베타 값"
,
"info"
:
"손실 함수에서 베타 매개 변수의 값."
,
},
"ja"
:
{
"label"
:
"Beta 値"
,
"info"
:
"損失関数における beta ハイパーパラメータの値。"
,
},
},
"pref_ftx"
:
{
"en"
:
{
"label"
:
"Ftx gamma"
,
"info"
:
"The weight of SFT loss in the final loss."
,
},
"ru"
:
{
"label"
:
"Ftx гамма"
,
"info"
:
"Вес потери SFT в итоговой потере."
,
},
"zh"
:
{
"label"
:
"Ftx gamma"
,
"info"
:
"损失函数中 SFT 损失的权重大小。"
,
},
"ko"
:
{
"label"
:
"Ftx 감마"
,
"info"
:
"최종 로스 함수에서 SFT 로스의 가중치."
,
},
"ja"
:
{
"label"
:
"Ftx gamma"
,
"info"
:
"損失関数における SFT 損失の重み。"
,
},
},
"pref_loss"
:
{
"en"
:
{
"label"
:
"Loss type"
,
"info"
:
"The type of the loss function."
,
},
"ru"
:
{
"label"
:
"Тип потерь"
,
"info"
:
"Тип функции потерь."
,
},
"zh"
:
{
"label"
:
"损失类型"
,
"info"
:
"损失函数的类型。"
,
},
"ko"
:
{
"label"
:
"로스 유형"
,
"info"
:
"로스 함수의 유형."
,
},
"ja"
:
{
"label"
:
"損失タイプ"
,
"info"
:
"損失関数のタイプ。"
,
},
},
"reward_model"
:
{
"en"
:
{
"label"
:
"Reward model"
,
"info"
:
"Adapter of the reward model in PPO training."
,
},
"ru"
:
{
"label"
:
"Модель вознаграждения"
,
"info"
:
"Адаптер модели вознаграждения для обучения PPO."
,
},
"zh"
:
{
"label"
:
"奖励模型"
,
"info"
:
"PPO 训练中奖励模型的适配器路径。"
,
},
"ko"
:
{
"label"
:
"리워드 모델"
,
"info"
:
"PPO 학습에서 사용할 리워드 모델의 어댑터."
,
},
"ja"
:
{
"label"
:
"報酬モデル"
,
"info"
:
"PPO トレーニングにおける報酬モデルのアダプター。"
,
},
},
"ppo_score_norm"
:
{
"en"
:
{
"label"
:
"Score norm"
,
"info"
:
"Normalizing scores in PPO training."
,
},
"ru"
:
{
"label"
:
"Норма оценок"
,
"info"
:
"Нормализация оценок в тренировке PPO."
,
},
"zh"
:
{
"label"
:
"归一化分数"
,
"info"
:
"PPO 训练中归一化奖励分数。"
,
},
"ko"
:
{
"label"
:
"스코어 정규화"
,
"info"
:
"PPO 학습에서 스코어를 정규화합니다."
,
},
"ja"
:
{
"label"
:
"スコア正規化"
,
"info"
:
"PPO トレーニングにおける報酬スコアの正規化。"
,
},
},
"ppo_whiten_rewards"
:
{
"en"
:
{
"label"
:
"Whiten rewards"
,
"info"
:
"Whiten the rewards in PPO training."
,
},
"ru"
:
{
"label"
:
"Белые вознаграждения"
,
"info"
:
"Осветлите вознаграждения в обучении PPO."
,
},
"zh"
:
{
"label"
:
"白化奖励"
,
"info"
:
"PPO 训练中将奖励分数做白化处理。"
,
},
"ko"
:
{
"label"
:
"보상 백화"
,
"info"
:
"PPO 훈련에서 보상을 백화(Whiten)합니다."
,
},
"ja"
:
{
"label"
:
"報酬のホワイトニング"
,
"info"
:
"PPO トレーニングにおいて報酬スコアをホワイトニング処理します。"
,
},
},
"mm_tab"
:
{
"en"
:
{
"label"
:
"Multimodal configurations"
,
},
"ru"
:
{
"label"
:
"Конфигурации мультимедиа"
,
},
"zh"
:
{
"label"
:
"多模态参数设置"
,
},
"ko"
:
{
"label"
:
"멀티모달 구성"
,
},
"ja"
:
{
"label"
:
"多モーダル設定"
,
},
},
"freeze_vision_tower"
:
{
"en"
:
{
"label"
:
"Freeze vision tower"
,
"info"
:
"Freeze the vision tower in the model."
,
},
"ru"
:
{
"label"
:
"Заморозить башню визиона"
,
"info"
:
"Заморозить башню визиона в модели."
,
},
"zh"
:
{
"label"
:
"冻结视觉编码器"
,
"info"
:
"冻结模型中的视觉编码器。"
,
},
"ko"
:
{
"label"
:
"비전 타워 고정"
,
"info"
:
"모델의 비전 타워를 고정합니다."
,
},
"ja"
:
{
"label"
:
"ビジョンタワーの固定"
,
"info"
:
"モデルのビジョンタワーを固定します。"
,
},
},
"freeze_multi_modal_projector"
:
{
"en"
:
{
"label"
:
"Freeze multi-modal projector"
,
"info"
:
"Freeze the multi-modal projector in the model."
,
},
"ru"
:
{
"label"
:
"Заморозить мультимодальный проектор"
,
"info"
:
"Заморозить мультимодальный проектор в модели."
,
},
"zh"
:
{
"label"
:
"冻结多模态投影器"
,
"info"
:
"冻结模型中的多模态投影器。"
,
},
"ko"
:
{
"label"
:
"멀티모달 프로젝터 고정"
,
"info"
:
"모델의 멀티모달 프로젝터를 고정합니다."
,
},
"ja"
:
{
"label"
:
"多モーダルプロジェクターの固定"
,
"info"
:
"モデルの多モーダルプロジェクターを固定します。"
,
},
},
"freeze_language_model"
:
{
"en"
:
{
"label"
:
"Freeze language model"
,
"info"
:
"Freeze the language model in the model."
,
},
"ru"
:
{
"label"
:
"Заморозить язык модели"
,
"info"
:
"Заморозить язык модели в модели."
,
},
"zh"
:
{
"label"
:
"冻结语言模型"
,
"info"
:
"冻结模型中的语言模型。"
,
},
"ko"
:
{
"label"
:
"언어 모델 고정"
,
"info"
:
"모델의 언어 모델을 고정합니다."
,
},
"ja"
:
{
"label"
:
"言語モデルの固定"
,
"info"
:
"モデルの言語モデルを固定します。"
,
},
},
"image_max_pixels"
:
{
"en"
:
{
"label"
:
"Image max pixels"
,
"info"
:
"The maximum number of pixels of image inputs."
,
},
"ru"
:
{
"label"
:
"Максимальное количество пикселей изображения"
,
"info"
:
"Максимальное количество пикселей изображения."
,
},
"zh"
:
{
"label"
:
"图像最大像素"
,
"info"
:
"输入图像的最大像素数。"
,
},
"ko"
:
{
"label"
:
"이미지 최대 픽셀"
,
"info"
:
"이미지 입력의 최대 픽셀 수입니다."
,
},
"ja"
:
{
"label"
:
"画像最大ピクセル"
,
"info"
:
"画像入力の最大ピクセル数です。"
,
},
},
"image_min_pixels"
:
{
"en"
:
{
"label"
:
"Image min pixels"
,
"info"
:
"The minimum number of pixels of image inputs."
,
},
"ru"
:
{
"label"
:
"Минимальное количество пикселей изображения"
,
"info"
:
"Минимальное количество пикселей изображения."
,
},
"zh"
:
{
"label"
:
"图像最小像素"
,
"info"
:
"输入图像的最小像素数。"
,
},
"ko"
:
{
"label"
:
"이미지 최소 픽셀"
,
"info"
:
"이미지 입력의 최소 픽셀 수입니다."
,
},
"ja"
:
{
"label"
:
"画像最小ピクセル"
,
"info"
:
"画像入力の最小ピクセル数です。"
,
},
},
"video_max_pixels"
:
{
"en"
:
{
"label"
:
"Video max pixels"
,
"info"
:
"The maximum number of pixels of video inputs."
,
},
"ru"
:
{
"label"
:
"Максимальное количество пикселей видео"
,
"info"
:
"Максимальное количество пикселей видео."
,
},
"zh"
:
{
"label"
:
"视频最大像素"
,
"info"
:
"输入视频的最大像素数。"
,
},
"ko"
:
{
"label"
:
"비디오 최대 픽셀"
,
"info"
:
"비디오 입력의 최대 픽셀 수입니다."
,
},
"ja"
:
{
"label"
:
"ビデオ最大ピクセル"
,
"info"
:
"ビデオ入力の最大ピクセル数です。"
,
},
},
"video_min_pixels"
:
{
"en"
:
{
"label"
:
"Video min pixels"
,
"info"
:
"The minimum number of pixels of video inputs."
,
},
"ru"
:
{
"label"
:
"Минимальное количество пикселей видео"
,
"info"
:
"Минимальное количество пикселей видео."
,
},
"zh"
:
{
"label"
:
"视频最小像素"
,
"info"
:
"输入视频的最小像素数。"
,
},
"ko"
:
{
"label"
:
"비디오 최소 픽셀"
,
"info"
:
"비디오 입력의 최소 픽셀 수입니다."
,
},
"ja"
:
{
"label"
:
"ビデオ最小ピクセル"
,
"info"
:
"ビデオ入力の最小ピクセル数です。"
,
},
},
"galore_tab"
:
{
"en"
:
{
"label"
:
"GaLore configurations"
,
},
"ru"
:
{
"label"
:
"Конфигурации GaLore"
,
},
"zh"
:
{
"label"
:
"GaLore 参数设置"
,
},
"ko"
:
{
"label"
:
"GaLore 구성"
,
},
"ja"
:
{
"label"
:
"GaLore 設定"
,
},
},
"use_galore"
:
{
"en"
:
{
"label"
:
"Use GaLore"
,
"info"
:
"Use [GaLore](https://github.com/jiaweizzhao/GaLore) optimizer."
,
},
"ru"
:
{
"label"
:
"Использовать GaLore"
,
"info"
:
"Используйте оптимизатор [GaLore](https://github.com/jiaweizzhao/GaLore)."
,
},
"zh"
:
{
"label"
:
"使用 GaLore"
,
"info"
:
"使用 [GaLore](https://github.com/jiaweizzhao/GaLore) 优化器。"
,
},
"ko"
:
{
"label"
:
"GaLore 사용"
,
"info"
:
"[GaLore](https://github.com/jiaweizzhao/GaLore) 최적화를 사용하세요."
,
},
"ja"
:
{
"label"
:
"GaLore を使用"
,
"info"
:
"[GaLore](https://github.com/jiaweizzhao/GaLore) オプティマイザーを使用します。"
,
},
},
"galore_rank"
:
{
"en"
:
{
"label"
:
"GaLore rank"
,
"info"
:
"The rank of GaLore gradients."
,
},
"ru"
:
{
"label"
:
"Ранг GaLore"
,
"info"
:
"Ранг градиентов GaLore."
,
},
"zh"
:
{
"label"
:
"GaLore 秩"
,
"info"
:
"GaLore 梯度的秩大小。"
,
},
"ko"
:
{
"label"
:
"GaLore 랭크"
,
"info"
:
"GaLore 그레디언트의 랭크."
,
},
"ja"
:
{
"label"
:
"GaLore ランク"
,
"info"
:
"GaLore 勾配のランク。"
,
},
},
"galore_update_interval"
:
{
"en"
:
{
"label"
:
"Update interval"
,
"info"
:
"Number of steps to update the GaLore projection."
,
},
"ru"
:
{
"label"
:
"Интервал обновления"
,
"info"
:
"Количество шагов для обновления проекции GaLore."
,
},
"zh"
:
{
"label"
:
"更新间隔"
,
"info"
:
"相邻两次投影更新的步数。"
,
},
"ko"
:
{
"label"
:
"업데이트 간격"
,
"info"
:
"GaLore 프로젝션을 업데이트할 간격의 스텝 수."
,
},
"ja"
:
{
"label"
:
"更新間隔"
,
"info"
:
"隣接する 2 回の投影更新間のステップ数。"
,
},
},
"galore_scale"
:
{
"en"
:
{
"label"
:
"GaLore scale"
,
"info"
:
"GaLore scaling coefficient."
,
},
"ru"
:
{
"label"
:
"LoRA Alpha"
,
"info"
:
"Коэффициент масштабирования GaLore."
,
},
"zh"
:
{
"label"
:
"GaLore 缩放系数"
,
"info"
:
"GaLore 缩放系数大小。"
,
},
"ko"
:
{
"label"
:
"GaLore 스케일"
,
"info"
:
"GaLore 스케일링 계수."
,
},
"ja"
:
{
"label"
:
"GaLore スケール"
,
"info"
:
"GaLore スケーリング係数。"
,
},
},
"galore_target"
:
{
"en"
:
{
"label"
:
"GaLore modules"
,
"info"
:
"Name(s) of modules to apply GaLore. Use commas to separate multiple modules."
,
},
"ru"
:
{
"label"
:
"Модули GaLore"
,
"info"
:
"Имена модулей для применения GaLore. Используйте запятые для разделения нескольких модулей."
,
},
"zh"
:
{
"label"
:
"GaLore 作用模块"
,
"info"
:
"应用 GaLore 的模块名称。使用英文逗号分隔多个名称。"
,
},
"ko"
:
{
"label"
:
"GaLore 모듈"
,
"info"
:
"GaLore를 적용할 모듈의 이름. 모듈 간에는 쉼표(,)로 구분하십시오."
,
},
"ja"
:
{
"label"
:
"GaLore モジュール"
,
"info"
:
"GaLore を適用するモジュールの名前。複数のモジュールを区切るにはカンマを使用します。"
,
},
},
"apollo_tab"
:
{
"en"
:
{
"label"
:
"APOLLO configurations"
,
},
"ru"
:
{
"label"
:
"Конфигурации APOLLO"
,
},
"zh"
:
{
"label"
:
"APOLLO 参数设置"
,
},
"ko"
:
{
"label"
:
"APOLLO 구성"
,
},
"ja"
:
{
"label"
:
"APOLLO 設定"
,
},
},
"use_apollo"
:
{
"en"
:
{
"label"
:
"Use APOLLO"
,
"info"
:
"Use [APOLLO](https://github.com/zhuhanqing/APOLLO) optimizer."
,
},
"ru"
:
{
"label"
:
"Использовать APOLLO"
,
"info"
:
"Используйте оптимизатор [APOLLO](https://github.com/zhuhanqing/APOLLO)."
,
},
"zh"
:
{
"label"
:
"使用 APOLLO"
,
"info"
:
"使用 [APOLLO](https://github.com/zhuhanqing/APOLLO) 优化器。"
,
},
"ko"
:
{
"label"
:
"APOLLO 사용"
,
"info"
:
"[APOLLO](https://github.com/zhuhanqing/APOLLO) 최적화를 사용하세요."
,
},
"ja"
:
{
"label"
:
"APOLLO を使用"
,
"info"
:
"[APOLLO](https://github.com/zhuhanqing/APOLLO) オプティマイザーを使用します。"
,
},
},
"apollo_rank"
:
{
"en"
:
{
"label"
:
"APOLLO rank"
,
"info"
:
"The rank of APOLLO gradients."
,
},
"ru"
:
{
"label"
:
"Ранг APOLLO"
,
"info"
:
"Ранг градиентов APOLLO."
,
},
"zh"
:
{
"label"
:
"APOLLO 秩"
,
"info"
:
"APOLLO 梯度的秩大小。"
,
},
"ko"
:
{
"label"
:
"APOLLO 랭크"
,
"info"
:
"APOLLO 그레디언트의 랭크."
,
},
"ja"
:
{
"label"
:
"APOLLO ランク"
,
"info"
:
"APOLLO 勾配のランク。"
,
},
},
"apollo_update_interval"
:
{
"en"
:
{
"label"
:
"Update interval"
,
"info"
:
"Number of steps to update the APOLLO projection."
,
},
"ru"
:
{
"label"
:
"Интервал обновления"
,
"info"
:
"Количество шагов для обновления проекции APOLLO."
,
},
"zh"
:
{
"label"
:
"更新间隔"
,
"info"
:
"相邻两次投影更新的步数。"
,
},
"ko"
:
{
"label"
:
"업데이트 간격"
,
"info"
:
"APOLLO 프로젝션을 업데이트할 간격의 스텝 수."
,
},
"ja"
:
{
"label"
:
"更新間隔"
,
"info"
:
"隣接する 2 回の投影更新間のステップ数。"
,
},
},
"apollo_scale"
:
{
"en"
:
{
"label"
:
"APOLLO scale"
,
"info"
:
"APOLLO scaling coefficient."
,
},
"ru"
:
{
"label"
:
"LoRA Alpha"
,
"info"
:
"Коэффициент масштабирования APOLLO."
,
},
"zh"
:
{
"label"
:
"APOLLO 缩放系数"
,
"info"
:
"APOLLO 缩放系数大小。"
,
},
"ko"
:
{
"label"
:
"APOLLO 스케일"
,
"info"
:
"APOLLO 스케일링 계수."
,
},
"ja"
:
{
"label"
:
"APOLLO スケール"
,
"info"
:
"APOLLO スケーリング係数。"
,
},
},
"apollo_target"
:
{
"en"
:
{
"label"
:
"APOLLO modules"
,
"info"
:
"Name(s) of modules to apply APOLLO. Use commas to separate multiple modules."
,
},
"ru"
:
{
"label"
:
"Модули APOLLO"
,
"info"
:
"Имена модулей для применения APOLLO. Используйте запятые для разделения нескольких модулей."
,
},
"zh"
:
{
"label"
:
"APOLLO 作用模块"
,
"info"
:
"应用 APOLLO 的模块名称。使用英文逗号分隔多个名称。"
,
},
"ko"
:
{
"label"
:
"APOLLO 모듈"
,
"info"
:
"APOLLO를 적용할 모듈의 이름. 모듈 간에는 쉼표(,)로 구분하십시오."
,
},
"ja"
:
{
"label"
:
"APOLLO モジュール"
,
"info"
:
"APOLLO を適用するモジュールの名前。複数のモジュールを区切るにはカンマを使用します。"
,
},
},
"badam_tab"
:
{
"en"
:
{
"label"
:
"BAdam configurations"
,
},
"ru"
:
{
"label"
:
"Конфигурации BAdam"
,
},
"zh"
:
{
"label"
:
"BAdam 参数设置"
,
},
"ko"
:
{
"label"
:
"BAdam 설정"
,
},
"ja"
:
{
"label"
:
"BAdam 設定"
,
},
},
"use_badam"
:
{
"en"
:
{
"label"
:
"Use BAdam"
,
"info"
:
"Enable the [BAdam](https://github.com/Ledzy/BAdam) optimizer."
,
},
"ru"
:
{
"label"
:
"Использовать BAdam"
,
"info"
:
"Включите оптимизатор [BAdam](https://github.com/Ledzy/BAdam)."
,
},
"zh"
:
{
"label"
:
"使用 BAdam"
,
"info"
:
"使用 [BAdam](https://github.com/Ledzy/BAdam) 优化器。"
,
},
"ko"
:
{
"label"
:
"BAdam 사용"
,
"info"
:
"[BAdam](https://github.com/Ledzy/BAdam) 옵티마이저를 사용합니다."
,
},
"ja"
:
{
"label"
:
"BAdam を使用"
,
"info"
:
"[BAdam](https://github.com/Ledzy/BAdam) オプティマイザーを使用します。"
,
},
},
"badam_mode"
:
{
"en"
:
{
"label"
:
"BAdam mode"
,
"info"
:
"Whether to use layer-wise or ratio-wise BAdam optimizer."
,
},
"ru"
:
{
"label"
:
"Режим BAdam"
,
"info"
:
"Использовать ли оптимизатор BAdam с послоевой или пропорциональной настройкой."
,
},
"zh"
:
{
"label"
:
"BAdam 模式"
,
"info"
:
"使用 layer-wise 或 ratio-wise BAdam 优化器。"
,
},
"ko"
:
{
"label"
:
"BAdam 모드"
,
"info"
:
"레이어-BAdam 옵티마이저인지 비율-BAdam 옵티마이저인지."
,
},
"ja"
:
{
"label"
:
"BAdam モード"
,
"info"
:
"layer-wise または ratio-wise BAdam オプティマイザーを使用します。"
,
},
},
"badam_switch_mode"
:
{
"en"
:
{
"label"
:
"Switch mode"
,
"info"
:
"The strategy of picking block to update for layer-wise BAdam."
,
},
"ru"
:
{
"label"
:
"Режим переключения"
,
"info"
:
"Стратегия выбора блока для обновления для послойного BAdam."
,
},
"zh"
:
{
"label"
:
"切换策略"
,
"info"
:
"Layer-wise BAdam 优化器的块切换策略。"
,
},
"ko"
:
{
"label"
:
"스위치 모드"
,
"info"
:
"레이어-BAdam을 위한 블록 선택 전략."
,
},
"ja"
:
{
"label"
:
"切り替え戦略"
,
"info"
:
"Layer-wise BAdam オプティマイザーのブロック切り替え戦略。"
,
},
},
"badam_switch_interval"
:
{
"en"
:
{
"label"
:
"Switch interval"
,
"info"
:
"Number of steps to update the block for layer-wise BAdam."
,
},
"ru"
:
{
"label"
:
"Интервал переключения"
,
"info"
:
"количество шагов для обновления блока для пошагового BAdam."
,
},
"zh"
:
{
"label"
:
"切换频率"
,
"info"
:
"Layer-wise BAdam 优化器的块切换频率。"
,
},
"ko"
:
{
"label"
:
"전환 간격"
,
"info"
:
"레이어-BAdam을 위한 블록 업데이트 간 스텝 수."
,
},
"ja"
:
{
"label"
:
"切り替え頻度"
,
"info"
:
"Layer-wise BAdam オプティマイザーのブロック切り替え頻度。"
,
},
},
"badam_update_ratio"
:
{
"en"
:
{
"label"
:
"Update ratio"
,
"info"
:
"The ratio of the update for ratio-wise BAdam."
,
},
"ru"
:
{
"label"
:
"Коэффициент обновления"
,
"info"
:
"Коэффициент обновления для BAdam с учётом соотношений."
,
},
"zh"
:
{
"label"
:
"Block 更新比例"
,
"info"
:
"Ratio-wise BAdam 优化器的更新比例。"
,
},
"ko"
:
{
"label"
:
"업데이트 비율"
,
"info"
:
"비율-BAdam의 업데이트 비율."
,
},
"ja"
:
{
"label"
:
"ブロック更新比率"
,
"info"
:
"Ratio-wise BAdam オプティマイザーの更新比率。"
,
},
},
"swanlab_tab"
:
{
"en"
:
{
"label"
:
"SwanLab configurations"
,
},
"ru"
:
{
"label"
:
"Конфигурации SwanLab"
,
},
"zh"
:
{
"label"
:
"SwanLab 参数设置"
,
},
"ko"
:
{
"label"
:
"SwanLab 설정"
,
},
"ja"
:
{
"label"
:
"SwanLab 設定"
,
},
},
"use_swanlab"
:
{
"en"
:
{
"label"
:
"Use SwanLab"
,
"info"
:
"Enable [SwanLab](https://swanlab.cn/) for experiment tracking and visualization."
,
},
"ru"
:
{
"label"
:
"Использовать SwanLab"
,
"info"
:
"Включить [SwanLab](https://swanlab.cn/) для отслеживания и визуализации экспериментов."
,
},
"zh"
:
{
"label"
:
"使用 SwanLab"
,
"info"
:
"启用 [SwanLab](https://swanlab.cn/) 进行实验跟踪和可视化。"
,
},
"ko"
:
{
"label"
:
"SwanLab 사용"
,
"info"
:
"[SwanLab](https://swanlab.cn/) 를 사용하여 실험을 추적하고 시각화합니다."
,
},
"ja"
:
{
"label"
:
"SwanLab を使用"
,
"info"
:
"[SwanLab](https://swanlab.cn/) を有効にして実験の追跡と可視化を行います。"
,
},
},
"swanlab_project"
:
{
"en"
:
{
"label"
:
"SwanLab project"
,
},
"ru"
:
{
"label"
:
"SwanLab Проект"
,
},
"zh"
:
{
"label"
:
"SwanLab 项目名"
,
},
"ko"
:
{
"label"
:
"SwanLab 프로젝트"
,
},
"ja"
:
{
"label"
:
"SwanLab プロジェクト"
,
},
},
"swanlab_run_name"
:
{
"en"
:
{
"label"
:
"SwanLab experiment name (optional)"
,
},
"ru"
:
{
"label"
:
"SwanLab Имя эксперимента (опционально)"
,
},
"zh"
:
{
"label"
:
"SwanLab 实验名(非必填)"
,
},
"ko"
:
{
"label"
:
"SwanLab 실험 이름 (선택 사항)"
,
},
"ja"
:
{
"label"
:
"SwanLab 実験名(オプション)"
,
},
},
"swanlab_workspace"
:
{
"en"
:
{
"label"
:
"SwanLab workspace (optional)"
,
"info"
:
"Workspace for SwanLab. Defaults to the personal workspace."
,
},
"ru"
:
{
"label"
:
"SwanLab Рабочая область (опционально)"
,
"info"
:
"Рабочая область SwanLab, если не заполнено, то по умолчанию в личной рабочей области."
,
},
"zh"
:
{
"label"
:
"SwanLab 工作区(非必填)"
,
"info"
:
"SwanLab 的工作区,默认在个人工作区下。"
,
},
"ko"
:
{
"label"
:
"SwanLab 작업 영역 (선택 사항)"
,
"info"
:
"SwanLab 조직의 작업 영역, 비어 있으면 기본적으로 개인 작업 영역에 있습니다."
,
},
"ja"
:
{
"label"
:
"SwanLab ワークスペース(オプション)"
,
"info"
:
"SwanLab のワークスペース。デフォルトでは個人ワークスペースです。"
,
},
},
"swanlab_api_key"
:
{
"en"
:
{
"label"
:
"SwanLab API key (optional)"
,
"info"
:
"API key for SwanLab."
,
},
"ru"
:
{
"label"
:
"SwanLab API ключ (опционально)"
,
"info"
:
"API ключ для SwanLab."
,
},
"zh"
:
{
"label"
:
"SwanLab API 密钥(非必填)"
,
"info"
:
"用于在编程环境登录 SwanLab,已登录则无需填写。"
,
},
"ko"
:
{
"label"
:
"SwanLab API 키 (선택 사항)"
,
"info"
:
"SwanLab의 API 키."
,
},
"ja"
:
{
"label"
:
"SwanLab API キー(オプション)"
,
"info"
:
"SwanLab の API キー。"
,
},
},
"swanlab_mode"
:
{
"en"
:
{
"label"
:
"SwanLab mode"
,
"info"
:
"Cloud or offline version."
,
},
"ru"
:
{
"label"
:
"SwanLab Режим"
,
"info"
:
"Версия в облаке или локальная версия."
,
},
"zh"
:
{
"label"
:
"SwanLab 模式"
,
"info"
:
"使用云端版或离线版 SwanLab。"
,
},
"ko"
:
{
"label"
:
"SwanLab 모드"
,
"info"
:
"클라우드 버전 또는 오프라인 버전."
,
},
"ja"
:
{
"label"
:
"SwanLab モード"
,
"info"
:
"クラウド版またはオフライン版 SwanLab を使用します。"
,
},
},
"swanlab_logdir"
:
{
"en"
:
{
"label"
:
"SwanLab log directory"
,
"info"
:
"The log directory for SwanLab."
,
},
"ru"
:
{
"label"
:
"SwanLab 로그 디렉토리"
,
"info"
:
"SwanLab의 로그 디렉토리."
,
},
"zh"
:
{
"label"
:
"SwanLab 日志目录"
,
"info"
:
"SwanLab 的日志目录。"
,
},
"ko"
:
{
"label"
:
"SwanLab 로그 디렉토리"
,
"info"
:
"SwanLab의 로그 디렉토리."
,
},
"ja"
:
{
"label"
:
"SwanLab ログ ディレクトリ"
,
"info"
:
"SwanLab のログ ディレクトリ。"
,
},
},
"cmd_preview_btn"
:
{
"en"
:
{
"value"
:
"Preview command"
,
},
"ru"
:
{
"value"
:
"Просмотр команды"
,
},
"zh"
:
{
"value"
:
"预览命令"
,
},
"ko"
:
{
"value"
:
"명령어 미리보기"
,
},
"ja"
:
{
"value"
:
"コマンドをプレビュー"
,
},
},
"arg_save_btn"
:
{
"en"
:
{
"value"
:
"Save arguments"
,
},
"ru"
:
{
"value"
:
"Сохранить аргументы"
,
},
"zh"
:
{
"value"
:
"保存训练参数"
,
},
"ko"
:
{
"value"
:
"Argument 저장"
,
},
"ja"
:
{
"value"
:
"引数を保存"
,
},
},
"arg_load_btn"
:
{
"en"
:
{
"value"
:
"Load arguments"
,
},
"ru"
:
{
"value"
:
"Загрузить аргументы"
,
},
"zh"
:
{
"value"
:
"载入训练参数"
,
},
"ko"
:
{
"value"
:
"Argument 불러오기"
,
},
"ja"
:
{
"value"
:
"引数を読み込む"
,
},
},
"start_btn"
:
{
"en"
:
{
"value"
:
"Start"
,
},
"ru"
:
{
"value"
:
"Начать"
,
},
"zh"
:
{
"value"
:
"开始"
,
},
"ko"
:
{
"value"
:
"시작"
,
},
"ja"
:
{
"value"
:
"開始"
,
},
},
"stop_btn"
:
{
"en"
:
{
"value"
:
"Abort"
,
},
"ru"
:
{
"value"
:
"Прервать"
,
},
"zh"
:
{
"value"
:
"中断"
,
},
"ko"
:
{
"value"
:
"중단"
,
},
"ja"
:
{
"value"
:
"中断"
,
},
},
"output_dir"
:
{
"en"
:
{
"label"
:
"Output dir"
,
"info"
:
"Directory for saving results."
,
},
"ru"
:
{
"label"
:
"Выходной каталог"
,
"info"
:
"Каталог для сохранения результатов."
,
},
"zh"
:
{
"label"
:
"输出目录"
,
"info"
:
"保存结果的路径。"
,
},
"ko"
:
{
"label"
:
"출력 디렉토리"
,
"info"
:
"결과를 저장할 디렉토리."
,
},
"ja"
:
{
"label"
:
"出力ディレクトリ"
,
"info"
:
"結果を保存するパス。"
,
},
},
"config_path"
:
{
"en"
:
{
"label"
:
"Config path"
,
"info"
:
"Path to config saving arguments."
,
},
"ru"
:
{
"label"
:
"Путь к конфигурации"
,
"info"
:
"Путь для сохранения аргументов конфигурации."
,
},
"zh"
:
{
"label"
:
"配置路径"
,
"info"
:
"保存训练参数的配置文件路径。"
,
},
"ko"
:
{
"label"
:
"설정 경로"
,
"info"
:
"Arguments 저장 파일 경로."
,
},
"ja"
:
{
"label"
:
"設定パス"
,
"info"
:
"トレーニングパラメータを保存する設定ファイルのパス。"
,
},
},
"device_count"
:
{
"en"
:
{
"label"
:
"Device count"
,
"info"
:
"Number of devices available."
,
},
"ru"
:
{
"label"
:
"Количество устройств"
,
"info"
:
"Количество доступных устройств."
,
},
"zh"
:
{
"label"
:
"设备数量"
,
"info"
:
"当前可用的运算设备数。"
,
},
"ko"
:
{
"label"
:
"디바이스 수"
,
"info"
:
"사용 가능한 디바이스 수."
,
},
"ja"
:
{
"label"
:
"デバイス数"
,
"info"
:
"現在利用可能な演算デバイス数。"
,
},
},
"ds_stage"
:
{
"en"
:
{
"label"
:
"DeepSpeed stage"
,
"info"
:
"DeepSpeed stage for distributed training."
,
},
"ru"
:
{
"label"
:
"Этап DeepSpeed"
,
"info"
:
"Этап DeepSpeed для распределенного обучения."
,
},
"zh"
:
{
"label"
:
"DeepSpeed stage"
,
"info"
:
"多卡训练的 DeepSpeed stage。"
,
},
"ko"
:
{
"label"
:
"DeepSpeed 단계"
,
"info"
:
"분산 학습을 위한 DeepSpeed 단계."
,
},
"ja"
:
{
"label"
:
"DeepSpeed stage"
,
"info"
:
"マルチ GPU トレーニングの DeepSpeed stage。"
,
},
},
"ds_offload"
:
{
"en"
:
{
"label"
:
"Enable offload"
,
"info"
:
"Enable DeepSpeed offload (slow down training)."
,
},
"ru"
:
{
"label"
:
"Включить выгрузку"
,
"info"
:
"включить выгрузку DeepSpeed (замедлит обучение)."
,
},
"zh"
:
{
"label"
:
"使用 offload"
,
"info"
:
"使用 DeepSpeed offload(会减慢速度)。"
,
},
"ko"
:
{
"label"
:
"오프로딩 활성화"
,
"info"
:
"DeepSpeed 오프로딩 활성화 (훈련 속도 느려짐)."
,
},
"ja"
:
{
"label"
:
"オフロードを使用"
,
"info"
:
"DeepSpeed オフロードを使用します(速度が遅くなります)。"
,
},
},
"output_box"
:
{
"en"
:
{
"value"
:
"Ready."
,
},
"ru"
:
{
"value"
:
"Готово."
,
},
"zh"
:
{
"value"
:
"准备就绪。"
,
},
"ko"
:
{
"value"
:
"준비 완료."
,
},
"ja"
:
{
"value"
:
"準備完了。"
,
},
},
"loss_viewer"
:
{
"en"
:
{
"label"
:
"Loss"
,
},
"ru"
:
{
"label"
:
"Потери"
,
},
"zh"
:
{
"label"
:
"损失"
,
},
"ko"
:
{
"label"
:
"손실"
,
},
"ja"
:
{
"label"
:
"損失"
,
},
},
"predict"
:
{
"en"
:
{
"label"
:
"Save predictions"
,
},
"ru"
:
{
"label"
:
"Сохранить предсказания"
,
},
"zh"
:
{
"label"
:
"保存预测结果"
,
},
"ko"
:
{
"label"
:
"예측 결과 저장"
,
},
"ja"
:
{
"label"
:
"予測結果を保存"
,
},
},
"infer_backend"
:
{
"en"
:
{
"label"
:
"Inference engine"
,
},
"ru"
:
{
"label"
:
"Инференс движок"
,
},
"zh"
:
{
"label"
:
"推理引擎"
,
},
"ko"
:
{
"label"
:
"추론 엔진"
,
},
"ja"
:
{
"label"
:
"推論エンジン"
,
},
},
"infer_dtype"
:
{
"en"
:
{
"label"
:
"Inference data type"
,
},
"ru"
:
{
"label"
:
"Тип данных для вывода"
,
},
"zh"
:
{
"label"
:
"推理数据类型"
,
},
"ko"
:
{
"label"
:
"추론 데이터 유형"
,
},
"ja"
:
{
"label"
:
"推論データタイプ"
,
},
},
"load_btn"
:
{
"en"
:
{
"value"
:
"Load model"
,
},
"ru"
:
{
"value"
:
"Загрузить модель"
,
},
"zh"
:
{
"value"
:
"加载模型"
,
},
"ko"
:
{
"value"
:
"모델 불러오기"
,
},
"ja"
:
{
"value"
:
"モデルを読み込む"
,
},
},
"unload_btn"
:
{
"en"
:
{
"value"
:
"Unload model"
,
},
"ru"
:
{
"value"
:
"Выгрузить модель"
,
},
"zh"
:
{
"value"
:
"卸载模型"
,
},
"ko"
:
{
"value"
:
"모델 언로드"
,
},
"ja"
:
{
"value"
:
"モデルをアンロード"
,
},
},
"info_box"
:
{
"en"
:
{
"value"
:
"Model unloaded, please load a model first."
,
},
"ru"
:
{
"value"
:
"Модель не загружена, загрузите модель сначала."
,
},
"zh"
:
{
"value"
:
"模型未加载,请先加载模型。"
,
},
"ko"
:
{
"value"
:
"모델이 언로드되었습니다. 모델을 먼저 불러오십시오."
,
},
"ja"
:
{
"value"
:
"モデルがロードされていません。最初にモデルをロードしてください。"
,
},
},
"role"
:
{
"en"
:
{
"label"
:
"Role"
,
},
"ru"
:
{
"label"
:
"Роль"
,
},
"zh"
:
{
"label"
:
"角色"
,
},
"ko"
:
{
"label"
:
"역할"
,
},
"ja"
:
{
"label"
:
"役割"
,
},
},
"system"
:
{
"en"
:
{
"placeholder"
:
"System prompt (optional)"
,
},
"ru"
:
{
"placeholder"
:
"Системный запрос (по желанию)"
,
},
"zh"
:
{
"placeholder"
:
"系统提示词(非必填)"
,
},
"ko"
:
{
"placeholder"
:
"시스템 프롬프트 (선택 사항)"
,
},
"ja"
:
{
"placeholder"
:
"システムプロンプト(オプション)"
,
},
},
"tools"
:
{
"en"
:
{
"placeholder"
:
"Tools (optional)"
,
},
"ru"
:
{
"placeholder"
:
"Инструменты (по желанию)"
,
},
"zh"
:
{
"placeholder"
:
"工具列表(非必填)"
,
},
"ko"
:
{
"placeholder"
:
"툴 (선택 사항)"
,
},
"ja"
:
{
"placeholder"
:
"ツールリスト(オプション)"
,
},
},
"image"
:
{
"en"
:
{
"label"
:
"Image (optional)"
,
},
"ru"
:
{
"label"
:
"Изображение (по желанию)"
,
},
"zh"
:
{
"label"
:
"图像(非必填)"
,
},
"ko"
:
{
"label"
:
"이미지 (선택 사항)"
,
},
"ja"
:
{
"label"
:
"画像(オプション)"
,
},
},
"video"
:
{
"en"
:
{
"label"
:
"Video (optional)"
,
},
"ru"
:
{
"label"
:
"Видео (по желанию)"
,
},
"zh"
:
{
"label"
:
"视频(非必填)"
,
},
"ko"
:
{
"label"
:
"비디오 (선택 사항)"
,
},
"ja"
:
{
"label"
:
"動画(オプション)"
,
},
},
"query"
:
{
"en"
:
{
"placeholder"
:
"Input..."
,
},
"ru"
:
{
"placeholder"
:
"Ввод..."
,
},
"zh"
:
{
"placeholder"
:
"输入..."
,
},
"ko"
:
{
"placeholder"
:
"입력..."
,
},
"ja"
:
{
"placeholder"
:
"入力..."
,
},
},
"submit_btn"
:
{
"en"
:
{
"value"
:
"Submit"
,
},
"ru"
:
{
"value"
:
"Отправить"
,
},
"zh"
:
{
"value"
:
"提交"
,
},
"ko"
:
{
"value"
:
"제출"
,
},
"ja"
:
{
"value"
:
"送信"
,
},
},
"max_length"
:
{
"en"
:
{
"label"
:
"Maximum length"
,
},
"ru"
:
{
"label"
:
"Максимальная длина"
,
},
"zh"
:
{
"label"
:
"最大长度"
,
},
"ko"
:
{
"label"
:
"최대 길이"
,
},
"ja"
:
{
"label"
:
"最大長"
,
},
},
"max_new_tokens"
:
{
"en"
:
{
"label"
:
"Maximum new tokens"
,
},
"ru"
:
{
"label"
:
"Максимальное количество новых токенов"
,
},
"zh"
:
{
"label"
:
"最大生成长度"
,
},
"ko"
:
{
"label"
:
"응답의 최대 길이"
,
},
"ja"
:
{
"label"
:
"最大生成長"
,
},
},
"top_p"
:
{
"en"
:
{
"label"
:
"Top-p"
,
},
"ru"
:
{
"label"
:
"Лучшие-p"
,
},
"zh"
:
{
"label"
:
"Top-p 采样值"
,
},
"ko"
:
{
"label"
:
"Top-p"
,
},
"ja"
:
{
"label"
:
"Top-p"
,
},
},
"temperature"
:
{
"en"
:
{
"label"
:
"Temperature"
,
},
"ru"
:
{
"label"
:
"Температура"
,
},
"zh"
:
{
"label"
:
"温度系数"
,
},
"ko"
:
{
"label"
:
"온도"
,
},
"ja"
:
{
"label"
:
"温度"
,
},
},
"skip_special_tokens"
:
{
"en"
:
{
"label"
:
"Skip special tokens"
,
},
"ru"
:
{
"label"
:
"Пропустить специальные токены"
,
},
"zh"
:
{
"label"
:
"跳过特殊 token"
,
},
"ko"
:
{
"label"
:
"스페셜 토큰을 건너뛰기"
,
},
"ja"
:
{
"label"
:
"スペシャルトークンをスキップ"
,
},
},
"escape_html"
:
{
"en"
:
{
"label"
:
"Escape HTML tags"
,
},
"ru"
:
{
"label"
:
"Исключить HTML теги"
,
},
"zh"
:
{
"label"
:
"转义 HTML 标签"
,
},
"ko"
:
{
"label"
:
"HTML 태그 이스케이프"
,
},
"ja"
:
{
"label"
:
"HTML タグをエスケープ"
,
},
},
"clear_btn"
:
{
"en"
:
{
"value"
:
"Clear history"
,
},
"ru"
:
{
"value"
:
"Очистить историю"
,
},
"zh"
:
{
"value"
:
"清空历史"
,
},
"ko"
:
{
"value"
:
"기록 지우기"
,
},
"ja"
:
{
"value"
:
"履歴をクリア"
,
},
},
"export_size"
:
{
"en"
:
{
"label"
:
"Max shard size (GB)"
,
"info"
:
"The maximum size for a model file."
,
},
"ru"
:
{
"label"
:
"Максимальный размер фрагмента (ГБ)"
,
"info"
:
"Максимальный размер файла модели."
,
},
"zh"
:
{
"label"
:
"最大分块大小(GB)"
,
"info"
:
"单个模型文件的最大大小。"
,
},
"ko"
:
{
"label"
:
"최대 샤드 크기 (GB)"
,
"info"
:
"모델 파일의 최대 크기."
,
},
"ja"
:
{
"label"
:
"最大シャードサイズ(GB)"
,
"info"
:
"単一のモデルファイルの最大サイズ。"
,
},
},
"export_quantization_bit"
:
{
"en"
:
{
"label"
:
"Export quantization bit."
,
"info"
:
"Quantizing the exported model."
,
},
"ru"
:
{
"label"
:
"Экспорт бита квантования"
,
"info"
:
"Квантование экспортируемой модели."
,
},
"zh"
:
{
"label"
:
"导出量化等级"
,
"info"
:
"量化导出模型。"
,
},
"ko"
:
{
"label"
:
"양자화 비트 내보내기"
,
"info"
:
"내보낸 모델의 양자화."
,
},
"ja"
:
{
"label"
:
"量子化ビットをエクスポート"
,
"info"
:
"エクスポートするモデルを量子化します。"
,
},
},
"export_quantization_dataset"
:
{
"en"
:
{
"label"
:
"Export quantization dataset"
,
"info"
:
"The calibration dataset used for quantization."
,
},
"ru"
:
{
"label"
:
"Экспорт набора данных для квантования"
,
"info"
:
"Набор данных калибровки, используемый для квантования."
,
},
"zh"
:
{
"label"
:
"导出量化数据集"
,
"info"
:
"量化过程中使用的校准数据集。"
,
},
"ko"
:
{
"label"
:
"양자화 데이터셋 내보내기"
,
"info"
:
"양자화에 사용되는 교정 데이터셋."
,
},
"ja"
:
{
"label"
:
"量子化データセットをエクスポート"
,
"info"
:
"量子化プロセスで使用されるキャリブレーションデータセット。"
,
},
},
"export_device"
:
{
"en"
:
{
"label"
:
"Export device"
,
"info"
:
"Which device should be used to export model."
,
},
"ru"
:
{
"label"
:
"Экспорт устройство"
,
"info"
:
"Какое устройство следует использовать для экспорта модели."
,
},
"zh"
:
{
"label"
:
"导出设备"
,
"info"
:
"导出模型使用的设备类型。"
,
},
"ko"
:
{
"label"
:
"내보낼 장치"
,
"info"
:
"모델을 내보내는 데 사용할 장치."
,
},
"ja"
:
{
"label"
:
"エクスポートデバイス"
,
"info"
:
"モデルをエクスポートするために使用するデバイスタイプ。"
,
},
},
"export_legacy_format"
:
{
"en"
:
{
"label"
:
"Export legacy format"
,
"info"
:
"Do not use safetensors to save the model."
,
},
"ru"
:
{
"label"
:
"Экспорт в устаревший формат"
,
"info"
:
"Не использовать safetensors для сохранения модели."
,
},
"zh"
:
{
"label"
:
"导出旧格式"
,
"info"
:
"不使用 safetensors 格式保存模型。"
,
},
"ko"
:
{
"label"
:
"레거시 형식 내보내기"
,
"info"
:
"모델을 저장하는 데 safetensors를 사용하지 않습니다."
,
},
"ja"
:
{
"label"
:
"レガシーフォーマットをエクスポート"
,
"info"
:
"safetensors フォーマットを使用せずにモデルを保存します。"
,
},
},
"export_dir"
:
{
"en"
:
{
"label"
:
"Export dir"
,
"info"
:
"Directory to save exported model."
,
},
"ru"
:
{
"label"
:
"Каталог экспорта"
,
"info"
:
"Каталог для сохранения экспортированной модели."
,
},
"zh"
:
{
"label"
:
"导出目录"
,
"info"
:
"保存导出模型的文件夹路径。"
,
},
"ko"
:
{
"label"
:
"내보내기 디렉토리"
,
"info"
:
"내보낸 모델을 저장할 디렉토리."
,
},
"ja"
:
{
"label"
:
"エクスポートディレクトリ"
,
"info"
:
"エクスポートしたモデルを保存するフォルダのパス。"
,
},
},
"export_hub_model_id"
:
{
"en"
:
{
"label"
:
"HF Hub ID (optional)"
,
"info"
:
"Repo ID for uploading model to Hugging Face hub."
,
},
"ru"
:
{
"label"
:
"HF Hub ID (опционально)"
,
"info"
:
"Идентификатор репозитория для загрузки модели на Hugging Face hub."
,
},
"zh"
:
{
"label"
:
"HF Hub ID(非必填)"
,
"info"
:
"用于将模型上传至 Hugging Face Hub 的仓库 ID。"
,
},
"ko"
:
{
"label"
:
"HF 허브 ID (선택 사항)"
,
"info"
:
"모델을 Hugging Face 허브에 업로드하기 위한 레포 ID."
,
},
"ja"
:
{
"label"
:
"HF Hub ID(オプション)"
,
"info"
:
"Hugging Face Hub にモデルをアップロードするためのリポジトリ ID。"
,
},
},
"export_btn"
:
{
"en"
:
{
"value"
:
"Export"
,
},
"ru"
:
{
"value"
:
"Экспорт"
,
},
"zh"
:
{
"value"
:
"开始导出"
,
},
"ko"
:
{
"value"
:
"내보내기"
,
},
"ja"
:
{
"value"
:
"エクスポート"
,
},
},
"device_memory"
:
{
"en"
:
{
"label"
:
"Device memory"
,
"info"
:
"Current memory usage of the device (GB)."
,
},
"ru"
:
{
"label"
:
"Память устройства"
,
"info"
:
"Текущая память на устройстве (GB)."
,
},
"zh"
:
{
"label"
:
"设备显存"
,
"info"
:
"当前设备的显存(GB)。"
,
},
"ko"
:
{
"label"
:
"디바이스 메모리"
,
"info"
:
"지금 사용 중인 기기 메모리 (GB)."
,
},
"ja"
:
{
"label"
:
"デバイスメモリ"
,
"info"
:
"現在のデバイスのメモリ(GB)。"
,
},
},
}
ALERTS
=
{
"err_conflict"
:
{
"en"
:
"A process is in running, please abort it first."
,
"ru"
:
"Процесс уже запущен, пожалуйста, сначала прервите его."
,
"zh"
:
"任务已存在,请先中断训练。"
,
"ko"
:
"프로세스가 실행 중입니다. 먼저 중단하십시오."
,
"ja"
:
"プロセスが実行中です。最初に中断してください。"
,
},
"err_exists"
:
{
"en"
:
"You have loaded a model, please unload it first."
,
"ru"
:
"Вы загрузили модель, сначала разгрузите ее."
,
"zh"
:
"模型已存在,请先卸载模型。"
,
"ko"
:
"모델이 로드되었습니다. 먼저 언로드하십시오."
,
"ja"
:
"モデルがロードされています。最初にアンロードしてください。"
,
},
"err_no_model"
:
{
"en"
:
"Please select a model."
,
"ru"
:
"Пожалуйста, выберите модель."
,
"zh"
:
"请选择模型。"
,
"ko"
:
"모델을 선택하십시오."
,
"ja"
:
"モデルを選択してください。"
,
},
"err_no_path"
:
{
"en"
:
"Model not found."
,
"ru"
:
"Модель не найдена."
,
"zh"
:
"模型未找到。"
,
"ko"
:
"모델을 찾을 수 없습니다."
,
"ja"
:
"モデルが見つかりません。"
,
},
"err_no_dataset"
:
{
"en"
:
"Please choose a dataset."
,
"ru"
:
"Пожалуйста, выберите набор данных."
,
"zh"
:
"请选择数据集。"
,
"ko"
:
"데이터 세트를 선택하십시오."
,
"ja"
:
"データセットを選択してください。"
,
},
"err_no_adapter"
:
{
"en"
:
"Please select an adapter."
,
"ru"
:
"Пожалуйста, выберите адаптер."
,
"zh"
:
"请选择适配器。"
,
"ko"
:
"어댑터를 선택하십시오."
,
"ja"
:
"アダプターを選択してください。"
,
},
"err_no_output_dir"
:
{
"en"
:
"Please provide output dir."
,
"ru"
:
"Пожалуйста, укажите выходную директорию."
,
"zh"
:
"请填写输出目录。"
,
"ko"
:
"출력 디렉토리를 제공하십시오."
,
"ja"
:
"出力ディレクトリを入力してください。"
,
},
"err_no_reward_model"
:
{
"en"
:
"Please select a reward model."
,
"ru"
:
"Пожалуйста, выберите модель вознаграждения."
,
"zh"
:
"请选择奖励模型。"
,
"ko"
:
"리워드 모델을 선택하십시오."
,
"ja"
:
"報酬モデルを選択してください。"
,
},
"err_no_export_dir"
:
{
"en"
:
"Please provide export dir."
,
"ru"
:
"Пожалуйста, укажите каталог для экспорта."
,
"zh"
:
"请填写导出目录。"
,
"ko"
:
"Export 디렉토리를 제공하십시오."
,
"ja"
:
"エクスポートディレクトリを入力してください。"
,
},
"err_gptq_lora"
:
{
"en"
:
"Please merge adapters before quantizing the model."
,
"ru"
:
"Пожалуйста, объедините адаптеры перед квантованием модели."
,
"zh"
:
"量化模型前请先合并适配器。"
,
"ko"
:
"모델을 양자화하기 전에 어댑터를 병합하십시오."
,
"ja"
:
"モデルを量子化する前にアダプターをマージしてください。"
,
},
"err_failed"
:
{
"en"
:
"Failed."
,
"ru"
:
"Ошибка."
,
"zh"
:
"训练出错。"
,
"ko"
:
"실패했습니다."
,
"ja"
:
"失敗しました。"
,
},
"err_demo"
:
{
"en"
:
"Training is unavailable in demo mode, duplicate the space to a private one first."
,
"ru"
:
"Обучение недоступно в демонстрационном режиме, сначала скопируйте пространство в частное."
,
"zh"
:
"展示模式不支持训练,请先复制到私人空间。"
,
"ko"
:
"데모 모드에서는 훈련을 사용할 수 없습니다. 먼저 프라이빗 레포지토리로 작업 공간을 복제하십시오."
,
"ja"
:
"デモモードではトレーニングは利用できません。最初にプライベートスペースに複製してください。"
,
},
"err_tool_name"
:
{
"en"
:
"Tool name not found."
,
"ru"
:
"Имя инструмента не найдено."
,
"zh"
:
"工具名称未找到。"
,
"ko"
:
"툴 이름을 찾을 수 없습니다."
,
"ja"
:
"ツール名が見つかりません。"
,
},
"err_json_schema"
:
{
"en"
:
"Invalid JSON schema."
,
"ru"
:
"Неверная схема JSON."
,
"zh"
:
"Json 格式错误。"
,
"ko"
:
"잘못된 JSON 스키마입니다."
,
"ja"
:
"JSON スキーマが無効です。"
,
},
"err_config_not_found"
:
{
"en"
:
"Config file is not found."
,
"ru"
:
"Файл конфигурации не найден."
,
"zh"
:
"未找到配置文件。"
,
"ko"
:
"Config 파일을 찾을 수 없습니다."
,
"ja"
:
"設定ファイルが見つかりません。"
,
},
"warn_no_cuda"
:
{
"en"
:
"CUDA environment was not detected."
,
"ru"
:
"Среда CUDA не обнаружена."
,
"zh"
:
"未检测到 CUDA 环境。"
,
"ko"
:
"CUDA 환경이 감지되지 않았습니다."
,
"ja"
:
"CUDA 環境が検出されませんでした。"
,
},
"warn_output_dir_exists"
:
{
"en"
:
"Output dir already exists, will resume training from here."
,
"ru"
:
"Выходной каталог уже существует, обучение будет продолжено отсюда."
,
"zh"
:
"输出目录已存在,将从该断点恢复训练。"
,
"ko"
:
"출력 디렉토리가 이미 존재합니다. 위 출력 디렉토리에 저장된 학습을 재개합니다."
,
"ja"
:
"出力ディレクトリが既に存在します。このチェックポイントからトレーニングを再開します。"
,
},
"warn_no_instruct"
:
{
"en"
:
"You are using a non-instruct model, please fine-tune it first."
,
"ru"
:
"Вы используете модель без инструкции, пожалуйста, primeros выполните донастройку этой модели."
,
"zh"
:
"您正在使用非指令模型,请先对其进行微调。"
,
"ko"
:
"당신은 지시하지 않은 모델을 사용하고 있습니다. 먼저 이를 미세 조정해 주세요."
,
"ja"
:
"インストラクションモデルを使用していません。まずモデルをアダプターに適合させてください。"
,
},
"info_aborting"
:
{
"en"
:
"Aborted, wait for terminating..."
,
"ru"
:
"Прервано, ожидание завершения..."
,
"zh"
:
"训练中断,正在等待进程结束……"
,
"ko"
:
"중단되었습니다. 종료를 기다리십시오..."
,
"ja"
:
"トレーニングが中断されました。プロセスの終了を待っています..."
,
},
"info_aborted"
:
{
"en"
:
"Ready."
,
"ru"
:
"Готово."
,
"zh"
:
"准备就绪。"
,
"ko"
:
"준비되었습니다."
,
"ja"
:
"準備完了。"
,
},
"info_finished"
:
{
"en"
:
"Finished."
,
"ru"
:
"Завершено."
,
"zh"
:
"训练完毕。"
,
"ko"
:
"완료되었습니다."
,
"ja"
:
"トレーニングが完了しました。"
,
},
"info_config_saved"
:
{
"en"
:
"Arguments have been saved at: "
,
"ru"
:
"Аргументы были сохранены по адресу: "
,
"zh"
:
"训练参数已保存至:"
,
"ko"
:
"매개변수가 저장되었습니다: "
,
"ja"
:
"トレーニングパラメータが保存されました: "
,
},
"info_config_loaded"
:
{
"en"
:
"Arguments have been restored."
,
"ru"
:
"Аргументы были восстановлены."
,
"zh"
:
"训练参数已载入。"
,
"ko"
:
"매개변수가 복원되었습니다."
,
"ja"
:
"トレーニングパラメータが読み込まれました。"
,
},
"info_loading"
:
{
"en"
:
"Loading model..."
,
"ru"
:
"Загрузка модели..."
,
"zh"
:
"加载中……"
,
"ko"
:
"모델 로딩 중..."
,
"ja"
:
"モデルをロード中..."
,
},
"info_unloading"
:
{
"en"
:
"Unloading model..."
,
"ru"
:
"Выгрузка модели..."
,
"zh"
:
"卸载中……"
,
"ko"
:
"모델 언로딩 중..."
,
"ja"
:
"モデルをアンロード中..."
,
},
"info_loaded"
:
{
"en"
:
"Model loaded, now you can chat with your model!"
,
"ru"
:
"Модель загружена, теперь вы можете общаться с вашей моделью!"
,
"zh"
:
"模型已加载,可以开始聊天了!"
,
"ko"
:
"모델이 로드되었습니다. 이제 모델과 채팅할 수 있습니다!"
,
"ja"
:
"モデルがロードされました。チャットを開始できます!"
,
},
"info_unloaded"
:
{
"en"
:
"Model unloaded."
,
"ru"
:
"Модель выгружена."
,
"zh"
:
"模型已卸载。"
,
"ko"
:
"모델이 언로드되었습니다."
,
"ja"
:
"モデルがアンロードされました。"
,
},
"info_thinking"
:
{
"en"
:
"🌀 Thinking..."
,
"ru"
:
"🌀 Думаю..."
,
"zh"
:
"🌀 思考中..."
,
"ko"
:
"🌀 생각 중..."
,
"ja"
:
"🌀 考えています..."
,
},
"info_thought"
:
{
"en"
:
"✅ Thought"
,
"ru"
:
"✅ Думать закончено"
,
"zh"
:
"✅ 思考完成"
,
"ko"
:
"✅ 생각이 완료되었습니다"
,
"ja"
:
"✅ 思考完了"
,
},
"info_exporting"
:
{
"en"
:
"Exporting model..."
,
"ru"
:
"Экспорт модели..."
,
"zh"
:
"正在导出模型……"
,
"ko"
:
"모델 내보내기 중..."
,
"ja"
:
"モデルをエクスポート中..."
,
},
"info_exported"
:
{
"en"
:
"Model exported."
,
"ru"
:
"Модель экспортирована."
,
"zh"
:
"模型导出完成。"
,
"ko"
:
"모델이 내보내졌습니다."
,
"ja"
:
"モデルのエクスポートが完了しました。"
,
},
"info_swanlab_link"
:
{
"en"
:
"### SwanLab Link
\n
"
,
"ru"
:
"### SwanLab ссылка
\n
"
,
"zh"
:
"### SwanLab 链接
\n
"
,
"ko"
:
"### SwanLab 링크
\n
"
,
"ja"
:
"### SwanLab リンク
\n
"
,
},
}
src/llamafactory/webui/manager.py
0 → 100644
View file @
c7c477c7
# Copyright 2025 the LlamaFactory team.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file 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.
from
collections.abc
import
Generator
from
typing
import
TYPE_CHECKING
if
TYPE_CHECKING
:
from
gradio.components
import
Component
class
Manager
:
r
"""A class to manage all the gradio components in Web UI."""
def
__init__
(
self
)
->
None
:
self
.
_id_to_elem
:
dict
[
str
,
Component
]
=
{}
self
.
_elem_to_id
:
dict
[
Component
,
str
]
=
{}
def
add_elems
(
self
,
tab_name
:
str
,
elem_dict
:
dict
[
str
,
"Component"
])
->
None
:
r
"""Add elements to manager."""
for
elem_name
,
elem
in
elem_dict
.
items
():
elem_id
=
f
"
{
tab_name
}
.
{
elem_name
}
"
self
.
_id_to_elem
[
elem_id
]
=
elem
self
.
_elem_to_id
[
elem
]
=
elem_id
def
get_elem_list
(
self
)
->
list
[
"Component"
]:
r
"""Return the list of all elements."""
return
list
(
self
.
_id_to_elem
.
values
())
def
get_elem_iter
(
self
)
->
Generator
[
tuple
[
str
,
"Component"
],
None
,
None
]:
r
"""Return an iterator over all elements with their names."""
for
elem_id
,
elem
in
self
.
_id_to_elem
.
items
():
yield
elem_id
.
split
(
"."
)[
-
1
],
elem
def
get_elem_by_id
(
self
,
elem_id
:
str
)
->
"Component"
:
r
"""Get element by id.
Example: top.lang, train.dataset
"""
return
self
.
_id_to_elem
[
elem_id
]
def
get_id_by_elem
(
self
,
elem
:
"Component"
)
->
str
:
r
"""Get id by element."""
return
self
.
_elem_to_id
[
elem
]
def
get_base_elems
(
self
)
->
set
[
"Component"
]:
r
"""Get the base elements that are commonly used."""
return
{
self
.
_id_to_elem
[
"top.lang"
],
self
.
_id_to_elem
[
"top.model_name"
],
self
.
_id_to_elem
[
"top.model_path"
],
self
.
_id_to_elem
[
"top.finetuning_type"
],
self
.
_id_to_elem
[
"top.checkpoint_path"
],
self
.
_id_to_elem
[
"top.quantization_bit"
],
self
.
_id_to_elem
[
"top.quantization_method"
],
self
.
_id_to_elem
[
"top.template"
],
self
.
_id_to_elem
[
"top.rope_scaling"
],
self
.
_id_to_elem
[
"top.booster"
],
}
src/llamafactory/webui/runner.py
0 → 100644
View file @
c7c477c7
# Copyright 2025 the LlamaFactory team.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file 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.
import
json
import
os
from
collections.abc
import
Generator
from
copy
import
deepcopy
from
subprocess
import
PIPE
,
Popen
,
TimeoutExpired
from
typing
import
TYPE_CHECKING
,
Any
,
Optional
from
transformers.utils
import
is_torch_npu_available
from
..extras.constants
import
LLAMABOARD_CONFIG
,
MULTIMODAL_SUPPORTED_MODELS
,
PEFT_METHODS
,
TRAINING_STAGES
from
..extras.misc
import
is_accelerator_available
,
torch_gc
from
..extras.packages
import
is_gradio_available
from
.common
import
(
DEFAULT_CACHE_DIR
,
DEFAULT_CONFIG_DIR
,
abort_process
,
calculate_pixels
,
gen_cmd
,
get_save_dir
,
load_args
,
load_config
,
load_eval_results
,
save_args
,
save_cmd
,
)
from
.control
import
get_trainer_info
from
.locales
import
ALERTS
,
LOCALES
if
is_gradio_available
():
import
gradio
as
gr
if
TYPE_CHECKING
:
from
gradio.components
import
Component
from
.manager
import
Manager
class
Runner
:
r
"""A class to manage the running status of the trainers."""
def
__init__
(
self
,
manager
:
"Manager"
,
demo_mode
:
bool
=
False
)
->
None
:
r
"""Init a runner."""
self
.
manager
=
manager
self
.
demo_mode
=
demo_mode
""" Resume """
self
.
trainer
:
Optional
[
Popen
]
=
None
self
.
do_train
=
True
self
.
running_data
:
dict
[
Component
,
Any
]
=
None
""" State """
self
.
aborted
=
False
self
.
running
=
False
def
set_abort
(
self
)
->
None
:
self
.
aborted
=
True
if
self
.
trainer
is
not
None
:
abort_process
(
self
.
trainer
.
pid
)
def
_initialize
(
self
,
data
:
dict
[
"Component"
,
Any
],
do_train
:
bool
,
from_preview
:
bool
)
->
str
:
r
"""Validate the configuration."""
get
=
lambda
elem_id
:
data
[
self
.
manager
.
get_elem_by_id
(
elem_id
)]
lang
,
model_name
,
model_path
=
get
(
"top.lang"
),
get
(
"top.model_name"
),
get
(
"top.model_path"
)
dataset
=
get
(
"train.dataset"
)
if
do_train
else
get
(
"eval.dataset"
)
if
self
.
running
:
return
ALERTS
[
"err_conflict"
][
lang
]
if
not
model_name
:
return
ALERTS
[
"err_no_model"
][
lang
]
if
not
model_path
:
return
ALERTS
[
"err_no_path"
][
lang
]
if
not
dataset
:
return
ALERTS
[
"err_no_dataset"
][
lang
]
if
not
from_preview
and
self
.
demo_mode
:
return
ALERTS
[
"err_demo"
][
lang
]
if
do_train
:
if
not
get
(
"train.output_dir"
):
return
ALERTS
[
"err_no_output_dir"
][
lang
]
try
:
json
.
loads
(
get
(
"train.extra_args"
))
except
json
.
JSONDecodeError
:
return
ALERTS
[
"err_json_schema"
][
lang
]
stage
=
TRAINING_STAGES
[
get
(
"train.training_stage"
)]
if
stage
==
"ppo"
and
not
get
(
"train.reward_model"
):
return
ALERTS
[
"err_no_reward_model"
][
lang
]
else
:
if
not
get
(
"eval.output_dir"
):
return
ALERTS
[
"err_no_output_dir"
][
lang
]
if
not
from_preview
and
not
is_accelerator_available
():
gr
.
Warning
(
ALERTS
[
"warn_no_cuda"
][
lang
])
return
""
def
_finalize
(
self
,
lang
:
str
,
finish_info
:
str
)
->
None
:
r
"""Clean the cached memory and resets the runner."""
finish_info
=
ALERTS
[
"info_aborted"
][
lang
]
if
self
.
aborted
else
finish_info
gr
.
Info
(
finish_info
)
self
.
trainer
=
None
self
.
aborted
=
False
self
.
running
=
False
self
.
running_data
=
None
torch_gc
()
def
_parse_train_args
(
self
,
data
:
dict
[
"Component"
,
Any
])
->
dict
[
str
,
Any
]:
r
"""Build and validate the training arguments."""
get
=
lambda
elem_id
:
data
[
self
.
manager
.
get_elem_by_id
(
elem_id
)]
model_name
,
finetuning_type
=
get
(
"top.model_name"
),
get
(
"top.finetuning_type"
)
user_config
=
load_config
()
args
=
dict
(
stage
=
TRAINING_STAGES
[
get
(
"train.training_stage"
)],
do_train
=
True
,
model_name_or_path
=
get
(
"top.model_path"
),
cache_dir
=
user_config
.
get
(
"cache_dir"
,
None
),
preprocessing_num_workers
=
16
,
finetuning_type
=
finetuning_type
,
template
=
get
(
"top.template"
),
rope_scaling
=
get
(
"top.rope_scaling"
)
if
get
(
"top.rope_scaling"
)
!=
"none"
else
None
,
flash_attn
=
"fa2"
if
get
(
"top.booster"
)
==
"flashattn2"
else
"auto"
,
use_unsloth
=
(
get
(
"top.booster"
)
==
"unsloth"
),
enable_liger_kernel
=
(
get
(
"top.booster"
)
==
"liger_kernel"
),
dataset_dir
=
get
(
"train.dataset_dir"
),
dataset
=
","
.
join
(
get
(
"train.dataset"
)),
cutoff_len
=
get
(
"train.cutoff_len"
),
learning_rate
=
float
(
get
(
"train.learning_rate"
)),
num_train_epochs
=
float
(
get
(
"train.num_train_epochs"
)),
max_samples
=
int
(
get
(
"train.max_samples"
)),
per_device_train_batch_size
=
get
(
"train.batch_size"
),
gradient_accumulation_steps
=
get
(
"train.gradient_accumulation_steps"
),
lr_scheduler_type
=
get
(
"train.lr_scheduler_type"
),
max_grad_norm
=
float
(
get
(
"train.max_grad_norm"
)),
logging_steps
=
get
(
"train.logging_steps"
),
save_steps
=
get
(
"train.save_steps"
),
warmup_steps
=
get
(
"train.warmup_steps"
),
neftune_noise_alpha
=
get
(
"train.neftune_alpha"
)
or
None
,
packing
=
get
(
"train.packing"
)
or
get
(
"train.neat_packing"
),
neat_packing
=
get
(
"train.neat_packing"
),
train_on_prompt
=
get
(
"train.train_on_prompt"
),
mask_history
=
get
(
"train.mask_history"
),
resize_vocab
=
get
(
"train.resize_vocab"
),
use_llama_pro
=
get
(
"train.use_llama_pro"
),
enable_thinking
=
get
(
"train.enable_thinking"
),
report_to
=
get
(
"train.report_to"
),
use_galore
=
get
(
"train.use_galore"
),
use_apollo
=
get
(
"train.use_apollo"
),
use_badam
=
get
(
"train.use_badam"
),
use_swanlab
=
get
(
"train.use_swanlab"
),
output_dir
=
get_save_dir
(
model_name
,
finetuning_type
,
get
(
"train.output_dir"
)),
fp16
=
(
get
(
"train.compute_type"
)
==
"fp16"
),
bf16
=
(
get
(
"train.compute_type"
)
==
"bf16"
),
pure_bf16
=
(
get
(
"train.compute_type"
)
==
"pure_bf16"
),
plot_loss
=
True
,
trust_remote_code
=
True
,
ddp_timeout
=
180000000
,
include_num_input_tokens_seen
=
True
,
)
args
.
update
(
json
.
loads
(
get
(
"train.extra_args"
)))
# checkpoints
if
get
(
"top.checkpoint_path"
):
if
finetuning_type
in
PEFT_METHODS
:
# list
args
[
"adapter_name_or_path"
]
=
","
.
join
(
[
get_save_dir
(
model_name
,
finetuning_type
,
adapter
)
for
adapter
in
get
(
"top.checkpoint_path"
)]
)
else
:
# str
args
[
"model_name_or_path"
]
=
get_save_dir
(
model_name
,
finetuning_type
,
get
(
"top.checkpoint_path"
))
# quantization
if
get
(
"top.quantization_bit"
)
!=
"none"
:
args
[
"quantization_bit"
]
=
int
(
get
(
"top.quantization_bit"
))
args
[
"quantization_method"
]
=
get
(
"top.quantization_method"
)
args
[
"double_quantization"
]
=
not
is_torch_npu_available
()
# freeze config
if
args
[
"finetuning_type"
]
==
"freeze"
:
args
[
"freeze_trainable_layers"
]
=
get
(
"train.freeze_trainable_layers"
)
args
[
"freeze_trainable_modules"
]
=
get
(
"train.freeze_trainable_modules"
)
args
[
"freeze_extra_modules"
]
=
get
(
"train.freeze_extra_modules"
)
or
None
# lora config
if
args
[
"finetuning_type"
]
==
"lora"
:
args
[
"lora_rank"
]
=
get
(
"train.lora_rank"
)
args
[
"lora_alpha"
]
=
get
(
"train.lora_alpha"
)
args
[
"lora_dropout"
]
=
get
(
"train.lora_dropout"
)
args
[
"loraplus_lr_ratio"
]
=
get
(
"train.loraplus_lr_ratio"
)
or
None
args
[
"create_new_adapter"
]
=
get
(
"train.create_new_adapter"
)
args
[
"use_rslora"
]
=
get
(
"train.use_rslora"
)
args
[
"use_dora"
]
=
get
(
"train.use_dora"
)
args
[
"pissa_init"
]
=
get
(
"train.use_pissa"
)
args
[
"pissa_convert"
]
=
get
(
"train.use_pissa"
)
args
[
"lora_target"
]
=
get
(
"train.lora_target"
)
or
"all"
args
[
"additional_target"
]
=
get
(
"train.additional_target"
)
or
None
if
args
[
"use_llama_pro"
]:
args
[
"freeze_trainable_layers"
]
=
get
(
"train.freeze_trainable_layers"
)
# rlhf config
if
args
[
"stage"
]
==
"ppo"
:
if
finetuning_type
in
PEFT_METHODS
:
args
[
"reward_model"
]
=
","
.
join
(
[
get_save_dir
(
model_name
,
finetuning_type
,
adapter
)
for
adapter
in
get
(
"train.reward_model"
)]
)
else
:
args
[
"reward_model"
]
=
get_save_dir
(
model_name
,
finetuning_type
,
get
(
"train.reward_model"
))
args
[
"reward_model_type"
]
=
"lora"
if
finetuning_type
==
"lora"
else
"full"
args
[
"ppo_score_norm"
]
=
get
(
"train.ppo_score_norm"
)
args
[
"ppo_whiten_rewards"
]
=
get
(
"train.ppo_whiten_rewards"
)
args
[
"top_k"
]
=
0
args
[
"top_p"
]
=
0.9
elif
args
[
"stage"
]
in
[
"dpo"
,
"kto"
]:
args
[
"pref_beta"
]
=
get
(
"train.pref_beta"
)
args
[
"pref_ftx"
]
=
get
(
"train.pref_ftx"
)
args
[
"pref_loss"
]
=
get
(
"train.pref_loss"
)
# multimodal config
if
model_name
in
MULTIMODAL_SUPPORTED_MODELS
:
args
[
"freeze_vision_tower"
]
=
get
(
"train.freeze_vision_tower"
)
args
[
"freeze_multi_modal_projector"
]
=
get
(
"train.freeze_multi_modal_projector"
)
args
[
"freeze_language_model"
]
=
get
(
"train.freeze_language_model"
)
args
[
"image_max_pixels"
]
=
calculate_pixels
(
get
(
"train.image_max_pixels"
))
args
[
"image_min_pixels"
]
=
calculate_pixels
(
get
(
"train.image_min_pixels"
))
args
[
"video_max_pixels"
]
=
calculate_pixels
(
get
(
"train.video_max_pixels"
))
args
[
"video_min_pixels"
]
=
calculate_pixels
(
get
(
"train.video_min_pixels"
))
# galore config
if
args
[
"use_galore"
]:
args
[
"galore_rank"
]
=
get
(
"train.galore_rank"
)
args
[
"galore_update_interval"
]
=
get
(
"train.galore_update_interval"
)
args
[
"galore_scale"
]
=
get
(
"train.galore_scale"
)
args
[
"galore_target"
]
=
get
(
"train.galore_target"
)
# apollo config
if
args
[
"use_apollo"
]:
args
[
"apollo_rank"
]
=
get
(
"train.apollo_rank"
)
args
[
"apollo_update_interval"
]
=
get
(
"train.apollo_update_interval"
)
args
[
"apollo_scale"
]
=
get
(
"train.apollo_scale"
)
args
[
"apollo_target"
]
=
get
(
"train.apollo_target"
)
# badam config
if
args
[
"use_badam"
]:
args
[
"badam_mode"
]
=
get
(
"train.badam_mode"
)
args
[
"badam_switch_mode"
]
=
get
(
"train.badam_switch_mode"
)
args
[
"badam_switch_interval"
]
=
get
(
"train.badam_switch_interval"
)
args
[
"badam_update_ratio"
]
=
get
(
"train.badam_update_ratio"
)
# swanlab config
if
get
(
"train.use_swanlab"
):
args
[
"swanlab_project"
]
=
get
(
"train.swanlab_project"
)
args
[
"swanlab_run_name"
]
=
get
(
"train.swanlab_run_name"
)
args
[
"swanlab_workspace"
]
=
get
(
"train.swanlab_workspace"
)
args
[
"swanlab_api_key"
]
=
get
(
"train.swanlab_api_key"
)
args
[
"swanlab_mode"
]
=
get
(
"train.swanlab_mode"
)
# eval config
if
get
(
"train.val_size"
)
>
1e-6
and
args
[
"stage"
]
!=
"ppo"
:
args
[
"val_size"
]
=
get
(
"train.val_size"
)
args
[
"eval_strategy"
]
=
"steps"
args
[
"eval_steps"
]
=
args
[
"save_steps"
]
args
[
"per_device_eval_batch_size"
]
=
args
[
"per_device_train_batch_size"
]
# ds config
if
get
(
"train.ds_stage"
)
!=
"none"
:
ds_stage
=
get
(
"train.ds_stage"
)
ds_offload
=
"offload_"
if
get
(
"train.ds_offload"
)
else
""
args
[
"deepspeed"
]
=
os
.
path
.
join
(
DEFAULT_CACHE_DIR
,
f
"ds_z
{
ds_stage
}
_
{
ds_offload
}
config.json"
)
return
args
def
_parse_eval_args
(
self
,
data
:
dict
[
"Component"
,
Any
])
->
dict
[
str
,
Any
]:
r
"""Build and validate the evaluation arguments."""
get
=
lambda
elem_id
:
data
[
self
.
manager
.
get_elem_by_id
(
elem_id
)]
model_name
,
finetuning_type
=
get
(
"top.model_name"
),
get
(
"top.finetuning_type"
)
user_config
=
load_config
()
args
=
dict
(
stage
=
"sft"
,
model_name_or_path
=
get
(
"top.model_path"
),
cache_dir
=
user_config
.
get
(
"cache_dir"
,
None
),
preprocessing_num_workers
=
16
,
finetuning_type
=
finetuning_type
,
quantization_method
=
get
(
"top.quantization_method"
),
template
=
get
(
"top.template"
),
rope_scaling
=
get
(
"top.rope_scaling"
)
if
get
(
"top.rope_scaling"
)
!=
"none"
else
None
,
flash_attn
=
"fa2"
if
get
(
"top.booster"
)
==
"flashattn2"
else
"auto"
,
use_unsloth
=
(
get
(
"top.booster"
)
==
"unsloth"
),
dataset_dir
=
get
(
"eval.dataset_dir"
),
eval_dataset
=
","
.
join
(
get
(
"eval.dataset"
)),
cutoff_len
=
get
(
"eval.cutoff_len"
),
max_samples
=
int
(
get
(
"eval.max_samples"
)),
per_device_eval_batch_size
=
get
(
"eval.batch_size"
),
predict_with_generate
=
True
,
report_to
=
"none"
,
max_new_tokens
=
get
(
"eval.max_new_tokens"
),
top_p
=
get
(
"eval.top_p"
),
temperature
=
get
(
"eval.temperature"
),
output_dir
=
get_save_dir
(
model_name
,
finetuning_type
,
get
(
"eval.output_dir"
)),
trust_remote_code
=
True
,
ddp_timeout
=
180000000
,
)
if
get
(
"eval.predict"
):
args
[
"do_predict"
]
=
True
else
:
args
[
"do_eval"
]
=
True
# checkpoints
if
get
(
"top.checkpoint_path"
):
if
finetuning_type
in
PEFT_METHODS
:
# list
args
[
"adapter_name_or_path"
]
=
","
.
join
(
[
get_save_dir
(
model_name
,
finetuning_type
,
adapter
)
for
adapter
in
get
(
"top.checkpoint_path"
)]
)
else
:
# str
args
[
"model_name_or_path"
]
=
get_save_dir
(
model_name
,
finetuning_type
,
get
(
"top.checkpoint_path"
))
# quantization
if
get
(
"top.quantization_bit"
)
!=
"none"
:
args
[
"quantization_bit"
]
=
int
(
get
(
"top.quantization_bit"
))
args
[
"quantization_method"
]
=
get
(
"top.quantization_method"
)
args
[
"double_quantization"
]
=
not
is_torch_npu_available
()
return
args
def
_preview
(
self
,
data
:
dict
[
"Component"
,
Any
],
do_train
:
bool
)
->
Generator
[
dict
[
"Component"
,
str
],
None
,
None
]:
r
"""Preview the training commands."""
output_box
=
self
.
manager
.
get_elem_by_id
(
"{}.output_box"
.
format
(
"train"
if
do_train
else
"eval"
))
error
=
self
.
_initialize
(
data
,
do_train
,
from_preview
=
True
)
if
error
:
gr
.
Warning
(
error
)
yield
{
output_box
:
error
}
else
:
args
=
self
.
_parse_train_args
(
data
)
if
do_train
else
self
.
_parse_eval_args
(
data
)
yield
{
output_box
:
gen_cmd
(
args
)}
def
_launch
(
self
,
data
:
dict
[
"Component"
,
Any
],
do_train
:
bool
)
->
Generator
[
dict
[
"Component"
,
Any
],
None
,
None
]:
r
"""Start the training process."""
output_box
=
self
.
manager
.
get_elem_by_id
(
"{}.output_box"
.
format
(
"train"
if
do_train
else
"eval"
))
error
=
self
.
_initialize
(
data
,
do_train
,
from_preview
=
False
)
if
error
:
gr
.
Warning
(
error
)
yield
{
output_box
:
error
}
else
:
self
.
do_train
,
self
.
running_data
=
do_train
,
data
args
=
self
.
_parse_train_args
(
data
)
if
do_train
else
self
.
_parse_eval_args
(
data
)
os
.
makedirs
(
args
[
"output_dir"
],
exist_ok
=
True
)
save_args
(
os
.
path
.
join
(
args
[
"output_dir"
],
LLAMABOARD_CONFIG
),
self
.
_build_config_dict
(
data
))
env
=
deepcopy
(
os
.
environ
)
env
[
"LLAMABOARD_ENABLED"
]
=
"1"
env
[
"LLAMABOARD_WORKDIR"
]
=
args
[
"output_dir"
]
if
args
.
get
(
"deepspeed"
,
None
)
is
not
None
:
env
[
"FORCE_TORCHRUN"
]
=
"1"
# NOTE: DO NOT USE shell=True to avoid security risk
self
.
trainer
=
Popen
([
"llamafactory-cli"
,
"train"
,
save_cmd
(
args
)],
env
=
env
,
stderr
=
PIPE
,
text
=
True
)
yield
from
self
.
monitor
()
def
_build_config_dict
(
self
,
data
:
dict
[
"Component"
,
Any
])
->
dict
[
str
,
Any
]:
r
"""Build a dictionary containing the current training configuration."""
config_dict
=
{}
skip_ids
=
[
"top.lang"
,
"top.model_path"
,
"train.output_dir"
,
"train.config_path"
]
for
elem
,
value
in
data
.
items
():
elem_id
=
self
.
manager
.
get_id_by_elem
(
elem
)
if
elem_id
not
in
skip_ids
:
config_dict
[
elem_id
]
=
value
return
config_dict
def
preview_train
(
self
,
data
):
yield
from
self
.
_preview
(
data
,
do_train
=
True
)
def
preview_eval
(
self
,
data
):
yield
from
self
.
_preview
(
data
,
do_train
=
False
)
def
run_train
(
self
,
data
):
yield
from
self
.
_launch
(
data
,
do_train
=
True
)
def
run_eval
(
self
,
data
):
yield
from
self
.
_launch
(
data
,
do_train
=
False
)
def
monitor
(
self
):
r
"""Monitorgit the training progress and logs."""
self
.
aborted
=
False
self
.
running
=
True
get
=
lambda
elem_id
:
self
.
running_data
[
self
.
manager
.
get_elem_by_id
(
elem_id
)]
lang
,
model_name
,
finetuning_type
=
get
(
"top.lang"
),
get
(
"top.model_name"
),
get
(
"top.finetuning_type"
)
output_dir
=
get
(
"{}.output_dir"
.
format
(
"train"
if
self
.
do_train
else
"eval"
))
output_path
=
get_save_dir
(
model_name
,
finetuning_type
,
output_dir
)
output_box
=
self
.
manager
.
get_elem_by_id
(
"{}.output_box"
.
format
(
"train"
if
self
.
do_train
else
"eval"
))
progress_bar
=
self
.
manager
.
get_elem_by_id
(
"{}.progress_bar"
.
format
(
"train"
if
self
.
do_train
else
"eval"
))
loss_viewer
=
self
.
manager
.
get_elem_by_id
(
"train.loss_viewer"
)
if
self
.
do_train
else
None
swanlab_link
=
self
.
manager
.
get_elem_by_id
(
"train.swanlab_link"
)
if
self
.
do_train
else
None
running_log
=
""
return_code
=
-
1
while
return_code
==
-
1
:
if
self
.
aborted
:
yield
{
output_box
:
ALERTS
[
"info_aborting"
][
lang
],
progress_bar
:
gr
.
Slider
(
visible
=
False
),
}
else
:
running_log
,
running_progress
,
running_info
=
get_trainer_info
(
lang
,
output_path
,
self
.
do_train
)
return_dict
=
{
output_box
:
running_log
,
progress_bar
:
running_progress
,
}
if
"loss_viewer"
in
running_info
:
return_dict
[
loss_viewer
]
=
running_info
[
"loss_viewer"
]
if
"swanlab_link"
in
running_info
:
return_dict
[
swanlab_link
]
=
running_info
[
"swanlab_link"
]
yield
return_dict
try
:
stderr
=
self
.
trainer
.
communicate
(
timeout
=
2
)[
1
]
return_code
=
self
.
trainer
.
returncode
except
TimeoutExpired
:
continue
if
return_code
==
0
or
self
.
aborted
:
finish_info
=
ALERTS
[
"info_finished"
][
lang
]
if
self
.
do_train
:
finish_log
=
ALERTS
[
"info_finished"
][
lang
]
+
"
\n\n
"
+
running_log
else
:
finish_log
=
load_eval_results
(
os
.
path
.
join
(
output_path
,
"all_results.json"
))
+
"
\n\n
"
+
running_log
else
:
print
(
stderr
)
finish_info
=
ALERTS
[
"err_failed"
][
lang
]
finish_log
=
ALERTS
[
"err_failed"
][
lang
]
+
f
" Exit code:
{
return_code
}
\n\n
```
\n
{
stderr
}
\n
```
\n
"
self
.
_finalize
(
lang
,
finish_info
)
return_dict
=
{
output_box
:
finish_log
,
progress_bar
:
gr
.
Slider
(
visible
=
False
)}
yield
return_dict
def
save_args
(
self
,
data
):
r
"""Save the training configuration to config path."""
output_box
=
self
.
manager
.
get_elem_by_id
(
"train.output_box"
)
error
=
self
.
_initialize
(
data
,
do_train
=
True
,
from_preview
=
True
)
if
error
:
gr
.
Warning
(
error
)
return
{
output_box
:
error
}
lang
=
data
[
self
.
manager
.
get_elem_by_id
(
"top.lang"
)]
config_path
=
data
[
self
.
manager
.
get_elem_by_id
(
"train.config_path"
)]
os
.
makedirs
(
DEFAULT_CONFIG_DIR
,
exist_ok
=
True
)
save_path
=
os
.
path
.
join
(
DEFAULT_CONFIG_DIR
,
config_path
)
save_args
(
save_path
,
self
.
_build_config_dict
(
data
))
return
{
output_box
:
ALERTS
[
"info_config_saved"
][
lang
]
+
save_path
}
def
load_args
(
self
,
lang
:
str
,
config_path
:
str
):
r
"""Load the training configuration from config path."""
output_box
=
self
.
manager
.
get_elem_by_id
(
"train.output_box"
)
config_dict
=
load_args
(
os
.
path
.
join
(
DEFAULT_CONFIG_DIR
,
config_path
))
if
config_dict
is
None
:
gr
.
Warning
(
ALERTS
[
"err_config_not_found"
][
lang
])
return
{
output_box
:
ALERTS
[
"err_config_not_found"
][
lang
]}
output_dict
:
dict
[
Component
,
Any
]
=
{
output_box
:
ALERTS
[
"info_config_loaded"
][
lang
]}
for
elem_id
,
value
in
config_dict
.
items
():
output_dict
[
self
.
manager
.
get_elem_by_id
(
elem_id
)]
=
value
return
output_dict
def
check_output_dir
(
self
,
lang
:
str
,
model_name
:
str
,
finetuning_type
:
str
,
output_dir
:
str
):
r
"""Restore the training status if output_dir exists."""
output_box
=
self
.
manager
.
get_elem_by_id
(
"train.output_box"
)
output_dict
:
dict
[
Component
,
Any
]
=
{
output_box
:
LOCALES
[
"output_box"
][
lang
][
"value"
]}
if
model_name
and
output_dir
and
os
.
path
.
isdir
(
get_save_dir
(
model_name
,
finetuning_type
,
output_dir
)):
gr
.
Warning
(
ALERTS
[
"warn_output_dir_exists"
][
lang
])
output_dict
[
output_box
]
=
ALERTS
[
"warn_output_dir_exists"
][
lang
]
output_dir
=
get_save_dir
(
model_name
,
finetuning_type
,
output_dir
)
config_dict
=
load_args
(
os
.
path
.
join
(
output_dir
,
LLAMABOARD_CONFIG
))
# load llamaboard config
for
elem_id
,
value
in
config_dict
.
items
():
output_dict
[
self
.
manager
.
get_elem_by_id
(
elem_id
)]
=
value
return
output_dict
src/train.py
0 → 100644
View file @
c7c477c7
# Copyright 2025 the LlamaFactory team.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file 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.
from
llamafactory.train.tuner
import
run_exp
def
main
():
run_exp
()
def
_mp_fn
(
index
):
# For xla_spawn (TPUs)
run_exp
()
if
__name__
==
"__main__"
:
main
()
src/webui.py
0 → 100644
View file @
c7c477c7
# Copyright 2025 the LlamaFactory team.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file 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.
import
os
from
llamafactory.extras.misc
import
fix_proxy
,
is_env_enabled
from
llamafactory.webui.interface
import
create_ui
def
main
():
gradio_ipv6
=
is_env_enabled
(
"GRADIO_IPV6"
)
gradio_share
=
is_env_enabled
(
"GRADIO_SHARE"
)
server_name
=
os
.
getenv
(
"GRADIO_SERVER_NAME"
,
"[::]"
if
gradio_ipv6
else
"0.0.0.0"
)
print
(
"Visit http://ip:port for Web UI, e.g., http://127.0.0.1:7860"
)
fix_proxy
(
ipv6_enabled
=
gradio_ipv6
)
create_ui
().
queue
().
launch
(
share
=
gradio_share
,
server_name
=
server_name
,
inbrowser
=
True
)
if
__name__
==
"__main__"
:
main
()
tests/check_license.py
0 → 100644
View file @
c7c477c7
# Copyright 2025 the LlamaFactory team.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file 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.
import
sys
from
pathlib
import
Path
KEYWORDS
=
(
"Copyright"
,
"2025"
,
"LlamaFactory"
)
def
main
():
path_list
:
list
[
Path
]
=
[]
for
check_dir
in
sys
.
argv
[
1
:]:
path_list
.
extend
(
Path
(
check_dir
).
glob
(
"**/*.py"
))
for
path
in
path_list
:
with
open
(
path
.
absolute
(),
encoding
=
"utf-8"
)
as
f
:
file_content
=
f
.
read
().
strip
().
split
(
"
\n
"
)
if
not
file_content
[
0
]:
continue
print
(
f
"Check license:
{
path
}
"
)
assert
all
(
keyword
in
file_content
[
0
]
for
keyword
in
KEYWORDS
),
f
"File
{
path
}
does not contain license."
if
__name__
==
"__main__"
:
main
()
tests/data/processor/test_feedback.py
0 → 100644
View file @
c7c477c7
# Copyright 2025 the LlamaFactory team.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file 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.
import
os
import
random
import
pytest
from
datasets
import
load_dataset
from
transformers
import
AutoTokenizer
from
llamafactory.extras.constants
import
IGNORE_INDEX
from
llamafactory.train.test_utils
import
load_dataset_module
DEMO_DATA
=
os
.
getenv
(
"DEMO_DATA"
,
"llamafactory/demo_data"
)
TINY_LLAMA3
=
os
.
getenv
(
"TINY_LLAMA3"
,
"llamafactory/tiny-random-Llama-3"
)
TRAIN_ARGS
=
{
"model_name_or_path"
:
TINY_LLAMA3
,
"stage"
:
"kto"
,
"do_train"
:
True
,
"finetuning_type"
:
"full"
,
"dataset"
:
"kto_en_demo"
,
"dataset_dir"
:
"REMOTE:"
+
DEMO_DATA
,
"template"
:
"llama3"
,
"cutoff_len"
:
8192
,
"output_dir"
:
"dummy_dir"
,
"overwrite_output_dir"
:
True
,
"fp16"
:
True
,
}
@
pytest
.
mark
.
parametrize
(
"num_samples"
,
[
16
])
def
test_feedback_data
(
num_samples
:
int
):
train_dataset
=
load_dataset_module
(
**
TRAIN_ARGS
)[
"train_dataset"
]
ref_tokenizer
=
AutoTokenizer
.
from_pretrained
(
TINY_LLAMA3
)
original_data
=
load_dataset
(
DEMO_DATA
,
name
=
"kto_en_demo"
,
split
=
"train"
)
indexes
=
random
.
choices
(
range
(
len
(
original_data
)),
k
=
num_samples
)
for
index
in
indexes
:
messages
=
original_data
[
"messages"
][
index
]
ref_input_ids
=
ref_tokenizer
.
apply_chat_template
(
messages
)
prompt_len
=
len
(
ref_tokenizer
.
apply_chat_template
(
messages
[:
-
1
],
add_generation_prompt
=
True
))
ref_labels
=
[
IGNORE_INDEX
]
*
prompt_len
+
ref_input_ids
[
prompt_len
:]
assert
train_dataset
[
"input_ids"
][
index
]
==
ref_input_ids
assert
train_dataset
[
"labels"
][
index
]
==
ref_labels
assert
train_dataset
[
"kto_tags"
][
index
]
==
original_data
[
"label"
][
index
]
tests/data/processor/test_pairwise.py
0 → 100644
View file @
c7c477c7
# Copyright 2025 the LlamaFactory team.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file 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.
import
os
import
random
import
pytest
from
datasets
import
load_dataset
from
transformers
import
AutoTokenizer
from
llamafactory.extras.constants
import
IGNORE_INDEX
from
llamafactory.train.test_utils
import
load_dataset_module
DEMO_DATA
=
os
.
getenv
(
"DEMO_DATA"
,
"llamafactory/demo_data"
)
TINY_LLAMA3
=
os
.
getenv
(
"TINY_LLAMA3"
,
"llamafactory/tiny-random-Llama-3"
)
TRAIN_ARGS
=
{
"model_name_or_path"
:
TINY_LLAMA3
,
"stage"
:
"rm"
,
"do_train"
:
True
,
"finetuning_type"
:
"full"
,
"dataset"
:
"dpo_en_demo"
,
"dataset_dir"
:
"REMOTE:"
+
DEMO_DATA
,
"template"
:
"llama3"
,
"cutoff_len"
:
8192
,
"output_dir"
:
"dummy_dir"
,
"overwrite_output_dir"
:
True
,
"fp16"
:
True
,
}
def
_convert_sharegpt_to_openai
(
messages
:
list
[
dict
[
str
,
str
]])
->
list
[
dict
[
str
,
str
]]:
role_mapping
=
{
"human"
:
"user"
,
"gpt"
:
"assistant"
,
"system"
:
"system"
}
new_messages
=
[]
for
message
in
messages
:
new_messages
.
append
({
"role"
:
role_mapping
[
message
[
"from"
]],
"content"
:
message
[
"value"
]})
return
new_messages
@
pytest
.
mark
.
parametrize
(
"num_samples"
,
[
16
])
def
test_pairwise_data
(
num_samples
:
int
):
train_dataset
=
load_dataset_module
(
**
TRAIN_ARGS
)[
"train_dataset"
]
ref_tokenizer
=
AutoTokenizer
.
from_pretrained
(
TINY_LLAMA3
)
original_data
=
load_dataset
(
DEMO_DATA
,
name
=
"dpo_en_demo"
,
split
=
"train"
)
indexes
=
random
.
choices
(
range
(
len
(
original_data
)),
k
=
num_samples
)
for
index
in
indexes
:
chosen_messages
=
original_data
[
"conversations"
][
index
]
+
[
original_data
[
"chosen"
][
index
]]
rejected_messages
=
original_data
[
"conversations"
][
index
]
+
[
original_data
[
"rejected"
][
index
]]
chosen_messages
=
_convert_sharegpt_to_openai
(
chosen_messages
)
rejected_messages
=
_convert_sharegpt_to_openai
(
rejected_messages
)
ref_chosen_input_ids
=
ref_tokenizer
.
apply_chat_template
(
chosen_messages
)
chosen_prompt_len
=
len
(
ref_tokenizer
.
apply_chat_template
(
chosen_messages
[:
-
1
],
add_generation_prompt
=
True
))
ref_chosen_labels
=
[
IGNORE_INDEX
]
*
chosen_prompt_len
+
ref_chosen_input_ids
[
chosen_prompt_len
:]
ref_rejected_input_ids
=
ref_tokenizer
.
apply_chat_template
(
rejected_messages
)
rejected_prompt_len
=
len
(
ref_tokenizer
.
apply_chat_template
(
rejected_messages
[:
-
1
],
add_generation_prompt
=
True
)
)
ref_rejected_labels
=
[
IGNORE_INDEX
]
*
rejected_prompt_len
+
ref_rejected_input_ids
[
rejected_prompt_len
:]
assert
train_dataset
[
"chosen_input_ids"
][
index
]
==
ref_chosen_input_ids
assert
train_dataset
[
"chosen_labels"
][
index
]
==
ref_chosen_labels
assert
train_dataset
[
"rejected_input_ids"
][
index
]
==
ref_rejected_input_ids
assert
train_dataset
[
"rejected_labels"
][
index
]
==
ref_rejected_labels
tests/data/processor/test_processor_utils.py
0 → 100644
View file @
c7c477c7
# Copyright 2025 the LlamaFactory team.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file 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.
import
pytest
from
llamafactory.data.processor.processor_utils
import
infer_seqlen
@
pytest
.
mark
.
parametrize
(
"test_input,test_output"
,
[
((
3000
,
2000
,
1000
),
(
600
,
400
)),
((
2000
,
3000
,
1000
),
(
400
,
600
)),
((
1000
,
100
,
1000
),
(
900
,
100
)),
((
100
,
1000
,
1000
),
(
100
,
900
)),
((
100
,
500
,
1000
),
(
100
,
500
)),
((
500
,
100
,
1000
),
(
500
,
100
)),
((
10
,
10
,
1000
),
(
10
,
10
)),
],
)
def
test_infer_seqlen
(
test_input
:
tuple
[
int
,
int
,
int
],
test_output
:
tuple
[
int
,
int
]):
assert
test_output
==
infer_seqlen
(
*
test_input
)
tests/data/processor/test_supervised.py
0 → 100644
View file @
c7c477c7
# Copyright 2025 the LlamaFactory team.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file 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.
import
os
import
random
import
pytest
from
datasets
import
load_dataset
from
transformers
import
AutoTokenizer
from
llamafactory.extras.constants
import
IGNORE_INDEX
from
llamafactory.train.test_utils
import
load_dataset_module
DEMO_DATA
=
os
.
getenv
(
"DEMO_DATA"
,
"llamafactory/demo_data"
)
TINY_LLAMA3
=
os
.
getenv
(
"TINY_LLAMA3"
,
"llamafactory/tiny-random-Llama-3"
)
TINY_DATA
=
os
.
getenv
(
"TINY_DATA"
,
"llamafactory/tiny-supervised-dataset"
)
TRAIN_ARGS
=
{
"model_name_or_path"
:
TINY_LLAMA3
,
"stage"
:
"sft"
,
"do_train"
:
True
,
"finetuning_type"
:
"full"
,
"template"
:
"llama3"
,
"cutoff_len"
:
8192
,
"output_dir"
:
"dummy_dir"
,
"overwrite_output_dir"
:
True
,
"fp16"
:
True
,
}
@
pytest
.
mark
.
parametrize
(
"num_samples"
,
[
16
])
def
test_supervised_single_turn
(
num_samples
:
int
):
train_dataset
=
load_dataset_module
(
dataset_dir
=
"ONLINE"
,
dataset
=
TINY_DATA
,
**
TRAIN_ARGS
)[
"train_dataset"
]
ref_tokenizer
=
AutoTokenizer
.
from_pretrained
(
TINY_LLAMA3
)
original_data
=
load_dataset
(
TINY_DATA
,
split
=
"train"
)
indexes
=
random
.
choices
(
range
(
len
(
original_data
)),
k
=
num_samples
)
for
index
in
indexes
:
prompt
=
original_data
[
"instruction"
][
index
]
if
original_data
[
"input"
][
index
]:
prompt
+=
"
\n
"
+
original_data
[
"input"
][
index
]
messages
=
[
{
"role"
:
"user"
,
"content"
:
prompt
},
{
"role"
:
"assistant"
,
"content"
:
original_data
[
"output"
][
index
]},
]
ref_input_ids
=
ref_tokenizer
.
apply_chat_template
(
messages
)
assert
train_dataset
[
"input_ids"
][
index
]
==
ref_input_ids
@
pytest
.
mark
.
parametrize
(
"num_samples"
,
[
8
])
def
test_supervised_multi_turn
(
num_samples
:
int
):
train_dataset
=
load_dataset_module
(
dataset_dir
=
"REMOTE:"
+
DEMO_DATA
,
dataset
=
"system_chat"
,
**
TRAIN_ARGS
)[
"train_dataset"
]
ref_tokenizer
=
AutoTokenizer
.
from_pretrained
(
TINY_LLAMA3
)
original_data
=
load_dataset
(
DEMO_DATA
,
name
=
"system_chat"
,
split
=
"train"
)
indexes
=
random
.
choices
(
range
(
len
(
original_data
)),
k
=
num_samples
)
for
index
in
indexes
:
ref_input_ids
=
ref_tokenizer
.
apply_chat_template
(
original_data
[
"messages"
][
index
])
assert
train_dataset
[
"input_ids"
][
index
]
==
ref_input_ids
@
pytest
.
mark
.
parametrize
(
"num_samples"
,
[
4
])
def
test_supervised_train_on_prompt
(
num_samples
:
int
):
train_dataset
=
load_dataset_module
(
dataset_dir
=
"REMOTE:"
+
DEMO_DATA
,
dataset
=
"system_chat"
,
train_on_prompt
=
True
,
**
TRAIN_ARGS
)[
"train_dataset"
]
ref_tokenizer
=
AutoTokenizer
.
from_pretrained
(
TINY_LLAMA3
)
original_data
=
load_dataset
(
DEMO_DATA
,
name
=
"system_chat"
,
split
=
"train"
)
indexes
=
random
.
choices
(
range
(
len
(
original_data
)),
k
=
num_samples
)
for
index
in
indexes
:
ref_ids
=
ref_tokenizer
.
apply_chat_template
(
original_data
[
"messages"
][
index
])
assert
train_dataset
[
"input_ids"
][
index
]
==
ref_ids
assert
train_dataset
[
"labels"
][
index
]
==
ref_ids
@
pytest
.
mark
.
parametrize
(
"num_samples"
,
[
4
])
def
test_supervised_mask_history
(
num_samples
:
int
):
train_dataset
=
load_dataset_module
(
dataset_dir
=
"REMOTE:"
+
DEMO_DATA
,
dataset
=
"system_chat"
,
mask_history
=
True
,
**
TRAIN_ARGS
)[
"train_dataset"
]
ref_tokenizer
=
AutoTokenizer
.
from_pretrained
(
TINY_LLAMA3
)
original_data
=
load_dataset
(
DEMO_DATA
,
name
=
"system_chat"
,
split
=
"train"
)
indexes
=
random
.
choices
(
range
(
len
(
original_data
)),
k
=
num_samples
)
for
index
in
indexes
:
messages
=
original_data
[
"messages"
][
index
]
ref_input_ids
=
ref_tokenizer
.
apply_chat_template
(
messages
)
prompt_len
=
len
(
ref_tokenizer
.
apply_chat_template
(
messages
[:
-
1
],
add_generation_prompt
=
True
))
ref_label_ids
=
[
IGNORE_INDEX
]
*
prompt_len
+
ref_input_ids
[
prompt_len
:]
assert
train_dataset
[
"input_ids"
][
index
]
==
ref_input_ids
assert
train_dataset
[
"labels"
][
index
]
==
ref_label_ids
tests/data/processor/test_unsupervised.py
0 → 100644
View file @
c7c477c7
# Copyright 2025 the LlamaFactory team.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file 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.
import
os
import
random
import
pytest
from
datasets
import
load_dataset
from
transformers
import
AutoTokenizer
from
llamafactory.train.test_utils
import
load_dataset_module
DEMO_DATA
=
os
.
getenv
(
"DEMO_DATA"
,
"llamafactory/demo_data"
)
TINY_LLAMA3
=
os
.
getenv
(
"TINY_LLAMA3"
,
"llamafactory/tiny-random-Llama-3"
)
TINY_DATA
=
os
.
getenv
(
"TINY_DATA"
,
"llamafactory/tiny-supervised-dataset"
)
TRAIN_ARGS
=
{
"model_name_or_path"
:
TINY_LLAMA3
,
"stage"
:
"ppo"
,
"do_train"
:
True
,
"finetuning_type"
:
"full"
,
"reward_model"
:
""
,
"reward_model_type"
:
"full"
,
"dataset"
:
"system_chat"
,
"dataset_dir"
:
"REMOTE:"
+
DEMO_DATA
,
"template"
:
"llama3"
,
"cutoff_len"
:
8192
,
"output_dir"
:
"dummy_dir"
,
"overwrite_output_dir"
:
True
,
"fp16"
:
True
,
}
@
pytest
.
mark
.
parametrize
(
"num_samples"
,
[
16
])
def
test_unsupervised_data
(
num_samples
:
int
):
train_dataset
=
load_dataset_module
(
**
TRAIN_ARGS
)[
"train_dataset"
]
ref_tokenizer
=
AutoTokenizer
.
from_pretrained
(
TINY_LLAMA3
)
original_data
=
load_dataset
(
DEMO_DATA
,
name
=
"system_chat"
,
split
=
"train"
)
indexes
=
random
.
choices
(
range
(
len
(
original_data
)),
k
=
num_samples
)
for
index
in
indexes
:
messages
=
original_data
[
"messages"
][
index
]
ref_ids
=
ref_tokenizer
.
apply_chat_template
(
messages
)
ref_input_ids
=
ref_tokenizer
.
apply_chat_template
(
messages
[:
-
1
],
add_generation_prompt
=
True
)
ref_labels
=
ref_ids
[
len
(
ref_input_ids
)
:]
assert
train_dataset
[
"input_ids"
][
index
]
==
ref_input_ids
assert
train_dataset
[
"labels"
][
index
]
==
ref_labels
tests/data/test_collator.py
0 → 100644
View file @
c7c477c7
# Copyright 2025 the LlamaFactory team.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file 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.
import
os
import
torch
from
PIL
import
Image
from
transformers
import
AutoConfig
,
AutoModelForVision2Seq
from
llamafactory.data
import
get_template_and_fix_tokenizer
from
llamafactory.data.collator
import
MultiModalDataCollatorForSeq2Seq
,
prepare_4d_attention_mask
from
llamafactory.extras.constants
import
IGNORE_INDEX
from
llamafactory.hparams
import
get_infer_args
from
llamafactory.model
import
load_tokenizer
TINY_LLAMA3
=
os
.
getenv
(
"TINY_LLAMA3"
,
"llamafactory/tiny-random-Llama-3"
)
def
test_base_collator
():
model_args
,
data_args
,
*
_
=
get_infer_args
({
"model_name_or_path"
:
TINY_LLAMA3
,
"template"
:
"default"
})
tokenizer_module
=
load_tokenizer
(
model_args
)
template
=
get_template_and_fix_tokenizer
(
tokenizer_module
[
"tokenizer"
],
data_args
)
data_collator
=
MultiModalDataCollatorForSeq2Seq
(
template
=
template
,
pad_to_multiple_of
=
8
,
label_pad_token_id
=
IGNORE_INDEX
,
**
tokenizer_module
,
)
p
=
tokenizer_module
[
"tokenizer"
].
pad_token_id
q
=
IGNORE_INDEX
features
=
[
{
"input_ids"
:
[
0
,
1
,
2
,
3
,
4
,
5
],
"attention_mask"
:
[
1
,
1
,
1
,
1
,
1
,
1
],
"labels"
:
[
q
,
q
,
2
,
3
,
4
,
5
],
},
{
"input_ids"
:
[
6
,
7
],
"attention_mask"
:
[
1
,
1
],
"labels"
:
[
q
,
7
],
},
]
batch_input
=
data_collator
(
features
)
expected_input
=
{
"input_ids"
:
[
[
0
,
1
,
2
,
3
,
4
,
5
,
p
,
p
],
[
6
,
7
,
p
,
p
,
p
,
p
,
p
,
p
],
],
"attention_mask"
:
[
[
1
,
1
,
1
,
1
,
1
,
1
,
0
,
0
],
[
1
,
1
,
0
,
0
,
0
,
0
,
0
,
0
],
],
"labels"
:
[
[
q
,
q
,
2
,
3
,
4
,
5
,
q
,
q
],
[
q
,
7
,
q
,
q
,
q
,
q
,
q
,
q
],
],
}
for
k
in
batch_input
.
keys
():
assert
batch_input
[
k
].
eq
(
torch
.
tensor
(
expected_input
[
k
])).
all
()
def
test_multimodal_collator
():
model_args
,
data_args
,
*
_
=
get_infer_args
(
{
"model_name_or_path"
:
"Qwen/Qwen2-VL-2B-Instruct"
,
"template"
:
"qwen2_vl"
}
)
tokenizer_module
=
load_tokenizer
(
model_args
)
template
=
get_template_and_fix_tokenizer
(
tokenizer_module
[
"tokenizer"
],
data_args
)
config
=
AutoConfig
.
from_pretrained
(
model_args
.
model_name_or_path
)
with
torch
.
device
(
"meta"
):
model
=
AutoModelForVision2Seq
.
from_config
(
config
)
data_collator
=
MultiModalDataCollatorForSeq2Seq
(
template
=
template
,
model
=
model
,
pad_to_multiple_of
=
4
,
label_pad_token_id
=
IGNORE_INDEX
,
**
tokenizer_module
,
)
p
=
tokenizer_module
[
"tokenizer"
].
pad_token_id
q
=
IGNORE_INDEX
s
=
tokenizer_module
[
"tokenizer"
].
convert_tokens_to_ids
(
"<|vision_start|>"
)
e
=
tokenizer_module
[
"tokenizer"
].
convert_tokens_to_ids
(
"<|vision_end|>"
)
m
=
tokenizer_module
[
"tokenizer"
].
convert_tokens_to_ids
(
"<|image_pad|>"
)
fake_image
=
Image
.
new
(
"RGB"
,
(
64
,
64
),
(
255
,
255
,
255
))
features
=
[
{
"input_ids"
:
[
0
,
1
,
2
,
3
],
"attention_mask"
:
[
1
,
1
,
1
,
1
],
"labels"
:
[
0
,
1
,
2
,
3
],
},
]
batch_input
=
data_collator
(
features
)
expected_input
=
{
"input_ids"
:
[
[
0
,
1
,
2
,
3
,
s
,
m
,
m
,
m
,
m
,
e
,
p
,
p
],
],
"attention_mask"
:
[
[
1
,
1
,
1
,
1
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
],
],
"labels"
:
[
[
0
,
1
,
2
,
3
,
q
,
q
,
q
,
q
,
q
,
q
,
q
,
q
],
],
"position_ids"
:
[
[[
0
,
1
,
2
,
3
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
]],
[[
0
,
1
,
2
,
3
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
]],
[[
0
,
1
,
2
,
3
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
]],
],
"rope_deltas"
:
[[
-
8
]],
**
tokenizer_module
[
"processor"
].
image_processor
(
fake_image
),
}
assert
batch_input
.
keys
()
==
expected_input
.
keys
()
for
k
in
batch_input
.
keys
():
assert
batch_input
[
k
].
eq
(
torch
.
tensor
(
expected_input
[
k
])).
all
()
def
test_4d_attention_mask
():
o
=
0.0
x
=
torch
.
finfo
(
torch
.
float16
).
min
attention_mask_with_indices
=
torch
.
tensor
(
[
[
1
,
1
,
2
,
2
,
2
,
0
],
[
1
,
2
,
2
,
3
,
3
,
3
],
]
)
attention_mask_computed
=
prepare_4d_attention_mask
(
attention_mask_with_indices
,
torch
.
float16
)
attention_mask_expected
=
torch
.
tensor
(
[
[
[
[
o
,
x
,
x
,
x
,
x
,
x
],
[
o
,
o
,
x
,
x
,
x
,
x
],
[
x
,
x
,
o
,
x
,
x
,
x
],
[
x
,
x
,
o
,
o
,
x
,
x
],
[
x
,
x
,
o
,
o
,
o
,
x
],
[
x
,
x
,
x
,
x
,
x
,
x
],
]
],
[
[
[
o
,
x
,
x
,
x
,
x
,
x
],
[
x
,
o
,
x
,
x
,
x
,
x
],
[
x
,
o
,
o
,
x
,
x
,
x
],
[
x
,
x
,
x
,
o
,
x
,
x
],
[
x
,
x
,
x
,
o
,
o
,
x
],
[
x
,
x
,
x
,
o
,
o
,
o
],
]
],
],
dtype
=
torch
.
float16
,
)
assert
list
(
attention_mask_computed
.
size
())
==
[
2
,
1
,
6
,
6
]
assert
torch
.
all
(
attention_mask_computed
==
attention_mask_expected
)
if
__name__
==
"__main__"
:
test_multimodal_collator
()
Prev
1
…
9
10
11
12
13
14
15
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