Commit 67a13a9f authored by zhougaofeng's avatar zhougaofeng
Browse files

Update model.properties, Dockerfile, requirements.txt, LICENSE.txt, README.md,...

Update model.properties, Dockerfile, requirements.txt, LICENSE.txt, README.md, whl.zip, doc/training_loss.png, doc/result.png, doc/internlm2_math.pdf, finetune/single_node.sh, finetune/multi_node.sh, finetune/data/README.md, finetune/data/identity.json, finetune/data/mllm_demo.json, finetune/data/dataset_info.json, finetune/data/alpaca_zh_demo.json, finetune/data/alpaca_en_demo.json, finetune/data/glaive_toolcall_zh_demo.json, finetune/data/dpo_zh_demo.json, finetune/data/c4_demo.json, finetune/data/glaive_toolcall_en_demo.json, finetune/data/kto_en_demo.json, finetune/data/dpo_en_demo.json, finetune/data/README_zh.md, finetune/data/wiki_demo.txt, finetune/scripts/cal_flops.py, finetune/scripts/length_cdf.py, finetune/scripts/cal_ppl.py, finetune/scripts/llamafy_qwen.py, finetune/scripts/cal_lr.py, finetune/scripts/llamafy_baichuan2.py, finetune/scripts/llama_pro.py, finetune/scripts/loftq_init.py, finetune/src/api.py, finetune/src/train.py, finetune/src/webui.py, finetune/src/llmfactory/__init__.py, finetune/src/llmfactory/cli.py, finetune/src/llmfactory/api/__init__.py, finetune/src/llmfactory/api/common.py, finetune/src/llmfactory/api/chat.py, finetune/src/llmfactory/api/app.py, finetune/src/llmfactory/api/protocol.py, finetune/src/llmfactory/chat/__init__.py, finetune/src/llmfactory/chat/base_engine.py, finetune/src/llmfactory/chat/vllm_engine.py, finetune/src/llmfactory/chat/chat_model.py, finetune/src/llmfactory/chat/hf_engine.py, finetune/src/llmfactory/data/__init__.py, finetune/src/llmfactory/data/loader.py, finetune/src/llmfactory/data/utils.py, finetune/src/llmfactory/data/collator.py, finetune/src/llmfactory/data/formatter.py, finetune/src/llmfactory/data/aligner.py, finetune/src/llmfactory/data/template.py, finetune/src/llmfactory/data/parser.py, finetune/src/llmfactory/data/preprocess.py, finetune/src/llmfactory/eval/__init__.py, finetune/src/llmfactory/eval/template.py, finetune/src/llmfactory/eval/evaluator.py, finetune/src/llmfactory/extras/__init__.py, finetune/src/llmfactory/extras/logging.py, finetune/src/llmfactory/extras/constants.py, finetune/src/llmfactory/extras/misc.py, finetune/src/llmfactory/extras/packages.py, finetune/src/llmfactory/extras/ploting.py, finetune/src/llmfactory/extras/callbacks.py, finetune/src/llmfactory/hparams/__init__.py, finetune/src/llmfactory/hparams/data_args.py, finetune/src/llmfactory/hparams/finetuning_args.py, finetune/src/llmfactory/hparams/generating_args.py, finetune/src/llmfactory/hparams/evaluation_args.py, finetune/src/llmfactory/hparams/model_args.py, finetune/src/llmfactory/hparams/parser.py, finetune/src/llmfactory/model/__init__.py, finetune/src/llmfactory/model/patcher.py, finetune/src/llmfactory/model/adapter.py, finetune/src/llmfactory/model/loader.py, finetune/src/llmfactory/model/utils/__init__.py, finetune/src/llmfactory/model/utils/misc.py, finetune/src/llmfactory/model/utils/checkpointing.py, finetune/src/llmfactory/model/utils/embedding.py, finetune/src/llmfactory/model/utils/attention.py, finetune/src/llmfactory/model/utils/longlora.py, finetune/src/llmfactory/model/utils/visual.py, finetune/src/llmfactory/model/utils/moe.py, finetune/src/llmfactory/model/utils/valuehead.py, finetune/src/llmfactory/model/utils/rope.py, finetune/src/llmfactory/model/utils/quantization.py, finetune/src/llmfactory/model/utils/mod.py, finetune/src/llmfactory/model/utils/unsloth.py, finetune/src/llmfactory/train/__init__.py, finetune/src/llmfactory/train/utils.py, finetune/src/llmfactory/train/tuner.py, finetune/src/llmfactory/train/dpo/__init__.py, finetune/src/llmfactory/train/dpo/trainer.py, finetune/src/llmfactory/train/dpo/workflow.py, finetune/src/llmfactory/train/kto/__init__.py, finetune/src/llmfactory/train/kto/trainer.py, finetune/src/llmfactory/train/kto/workflow.py, finetune/src/llmfactory/train/orpo/trainer.py, finetune/src/llmfactory/train/orpo/__init__.py, finetune/src/llmfactory/train/orpo/workflow.py, finetune/src/llmfactory/train/ppo/__init__.py, finetune/src/llmfactory/train/ppo/workflow.py, finetune/src/llmfactory/train/ppo/utils.py, finetune/src/llmfactory/train/ppo/trainer.py, finetune/src/llmfactory/train/pt/__init__.py, finetune/src/llmfactory/train/pt/workflow.py, finetune/src/llmfactory/train/pt/trainer.py, finetune/src/llmfactory/train/rm/__init__.py, finetune/src/llmfactory/train/rm/metric.py, finetune/src/llmfactory/train/rm/workflow.py, finetune/src/llmfactory/train/rm/trainer.py, finetune/src/llmfactory/train/sft/__init__.py, finetune/src/llmfactory/train/sft/metric.py, finetune/src/llmfactory/train/sft/trainer.py, finetune/src/llmfactory/train/sft/workflow.py, finetune/src/llmfactory/webui/__init__.py, finetune/src/llmfactory/webui/chatter.py, finetune/src/llmfactory/webui/common.py, finetune/src/llmfactory/webui/css.py, finetune/src/llmfactory/webui/manager.py, finetune/src/llmfactory/webui/engine.py, finetune/src/llmfactory/webui/runner.py, finetune/src/llmfactory/webui/interface.py, finetune/src/llmfactory/webui/utils.py, finetune/src/llmfactory/webui/locales.py, finetune/src/llmfactory/webui/components/__init__.py, finetune/src/llmfactory/webui/components/chatbot.py, finetune/src/llmfactory/webui/components/data.py, finetune/src/llmfactory/webui/components/eval.py, finetune/src/llmfactory/webui/components/export.py, finetune/src/llmfactory/webui/components/infer.py, finetune/src/llmfactory/webui/components/top.py, finetune/src/llmfactory/webui/components/train.py, inference/single_dcu.py files
parents
Pipeline #1202 canceled with stages
from typing import TYPE_CHECKING, Dict, Generator, List
from ...extras.misc import torch_gc
from ...extras.packages import is_gradio_available
from ...train.tuner import export_model
from ..common import get_save_dir
from ..locales import ALERTS
if is_gradio_available():
import gradio as gr
if TYPE_CHECKING:
from gradio.components import Component
from ..engine import Engine
GPTQ_BITS = ["8", "4", "3", "2"]
def save_model(
lang: str,
model_name: str,
model_path: str,
adapter_path: List[str],
finetuning_type: str,
template: str,
visual_inputs: bool,
export_size: int,
export_quantization_bit: int,
export_quantization_dataset: str,
export_device: str,
export_legacy_format: bool,
export_dir: str,
export_hub_model_id: str,
) -> Generator[str, None, None]:
error = ""
if not model_name:
error = ALERTS["err_no_model"][lang]
elif not model_path:
error = ALERTS["err_no_path"][lang]
elif not export_dir:
error = ALERTS["err_no_export_dir"][lang]
elif export_quantization_bit in GPTQ_BITS and not export_quantization_dataset:
error = ALERTS["err_no_dataset"][lang]
elif export_quantization_bit not in GPTQ_BITS and not adapter_path:
error = ALERTS["err_no_adapter"][lang]
elif export_quantization_bit in GPTQ_BITS and adapter_path:
error = ALERTS["err_gptq_lora"][lang]
if error:
gr.Warning(error)
yield error
return
if adapter_path:
adapter_name_or_path = ",".join(
[get_save_dir(model_name, finetuning_type, adapter) for adapter in adapter_path]
)
else:
adapter_name_or_path = None
args = dict(
model_name_or_path=model_path,
adapter_name_or_path=adapter_name_or_path,
finetuning_type=finetuning_type,
template=template,
visual_inputs=visual_inputs,
export_dir=export_dir,
export_hub_model_id=export_hub_model_id or None,
export_size=export_size,
export_quantization_bit=int(export_quantization_bit) if export_quantization_bit in GPTQ_BITS else None,
export_quantization_dataset=export_quantization_dataset,
export_device=export_device,
export_legacy_format=export_legacy_format,
)
yield ALERTS["info_exporting"][lang]
export_model(args)
torch_gc()
yield ALERTS["info_exported"][lang]
def create_export_tab(engine: "Engine") -> Dict[str, "Component"]:
with gr.Row():
export_size = gr.Slider(minimum=1, maximum=100, value=1, step=1)
export_quantization_bit = gr.Dropdown(choices=["none", "8", "4", "3", "2"], value="none")
export_quantization_dataset = gr.Textbox(value="data/c4_demo.json")
export_device = gr.Radio(choices=["cpu", "cuda"], value="cpu")
export_legacy_format = gr.Checkbox()
with gr.Row():
export_dir = gr.Textbox()
export_hub_model_id = gr.Textbox()
export_btn = gr.Button()
info_box = gr.Textbox(show_label=False, interactive=False)
export_btn.click(
save_model,
[
engine.manager.get_elem_by_id("top.lang"),
engine.manager.get_elem_by_id("top.model_name"),
engine.manager.get_elem_by_id("top.model_path"),
engine.manager.get_elem_by_id("top.adapter_path"),
engine.manager.get_elem_by_id("top.finetuning_type"),
engine.manager.get_elem_by_id("top.template"),
engine.manager.get_elem_by_id("top.visual_inputs"),
export_size,
export_quantization_bit,
export_quantization_dataset,
export_device,
export_legacy_format,
export_dir,
export_hub_model_id,
],
[info_box],
)
return dict(
export_size=export_size,
export_quantization_bit=export_quantization_bit,
export_quantization_dataset=export_quantization_dataset,
export_device=export_device,
export_legacy_format=export_legacy_format,
export_dir=export_dir,
export_hub_model_id=export_hub_model_id,
export_btn=export_btn,
info_box=info_box,
)
from typing import TYPE_CHECKING, Dict
from ...extras.packages import is_gradio_available
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()
infer_backend = gr.Dropdown(choices=["huggingface", "vllm"], value="huggingface")
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})
elem_dict.update(dict(infer_backend=infer_backend, 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.visual_inputs").change(
lambda enabled: gr.Column(visible=enabled),
[engine.manager.get_elem_by_id("top.visual_inputs")],
[chat_elems["image_box"]],
)
return elem_dict
from typing import TYPE_CHECKING, Dict
from ...data import templates
from ...extras.constants import METHODS, SUPPORTED_MODELS
from ...extras.packages import is_gradio_available
from ..common import get_model_path, get_template, get_visual, list_adapters, save_config
from ..utils import can_quantize
if is_gradio_available():
import gradio as gr
if TYPE_CHECKING:
from gradio.components import Component
def create_top() -> Dict[str, "Component"]:
available_models = list(SUPPORTED_MODELS.keys()) + ["Custom"]
with gr.Row():
lang = gr.Dropdown(choices=["en", "ru", "zh"], scale=1)
model_name = gr.Dropdown(choices=available_models, scale=3)
model_path = gr.Textbox(scale=3)
with gr.Row():
finetuning_type = gr.Dropdown(choices=METHODS, value="lora", scale=1)
adapter_path = gr.Dropdown(multiselect=True, allow_custom_value=True, scale=5)
refresh_btn = gr.Button(scale=1)
with gr.Accordion(open=False) as advanced_tab:
with gr.Row():
quantization_bit = gr.Dropdown(choices=["none", "8", "4"], value="none", scale=2)
template = gr.Dropdown(choices=list(templates.keys()), value="default", scale=2)
rope_scaling = gr.Radio(choices=["none", "linear", "dynamic"], value="none", scale=3)
booster = gr.Radio(choices=["none", "flashattn2", "unsloth"], value="none", scale=3)
visual_inputs = gr.Checkbox(scale=1)
model_name.change(list_adapters, [model_name, finetuning_type], [adapter_path], queue=False).then(
get_model_path, [model_name], [model_path], queue=False
).then(get_template, [model_name], [template], queue=False).then(
get_visual, [model_name], [visual_inputs], queue=False
) # do not save config since the below line will save
model_path.change(save_config, inputs=[lang, model_name, model_path], queue=False)
finetuning_type.change(list_adapters, [model_name, finetuning_type], [adapter_path], queue=False).then(
can_quantize, [finetuning_type], [quantization_bit], queue=False
)
refresh_btn.click(list_adapters, [model_name, finetuning_type], [adapter_path], queue=False)
return dict(
lang=lang,
model_name=model_name,
model_path=model_path,
finetuning_type=finetuning_type,
adapter_path=adapter_path,
refresh_btn=refresh_btn,
advanced_tab=advanced_tab,
quantization_bit=quantization_bit,
template=template,
rope_scaling=rope_scaling,
booster=booster,
visual_inputs=visual_inputs,
)
from typing import TYPE_CHECKING, Dict
from transformers.trainer_utils import SchedulerType
from ...extras.constants import TRAINING_STAGES
from ...extras.packages import is_gradio_available
from ..common import DEFAULT_DATA_DIR, autoset_packing, list_adapters, list_dataset
from ..components.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():
training_stage = gr.Dropdown(
choices=list(TRAINING_STAGES.keys()), value=list(TRAINING_STAGES.keys())[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=["fp16", "bf16", "fp32", "pure_bf16"], value="fp16")
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=65536, value=1024, 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)
optim = gr.Textbox(value="adamw_torch")
with gr.Row():
with gr.Column():
resize_vocab = gr.Checkbox()
packing = gr.Checkbox()
with gr.Column():
upcast_layernorm = gr.Checkbox()
use_llama_pro = gr.Checkbox()
with gr.Column():
shift_attn = gr.Checkbox()
report_to = gr.Checkbox()
input_elems.update(
{
logging_steps,
save_steps,
warmup_steps,
neftune_alpha,
optim,
resize_vocab,
packing,
upcast_layernorm,
use_llama_pro,
shift_attn,
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,
optim=optim,
resize_vocab=resize_vocab,
packing=packing,
upcast_layernorm=upcast_layernorm,
use_llama_pro=use_llama_pro,
shift_attn=shift_attn,
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():
with gr.Column(scale=1):
use_rslora = gr.Checkbox()
use_dora = 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,
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,
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"], 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 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=1024, value=200, step=1)
galore_scale = gr.Slider(minimum=0, maximum=1, value=0.25, step=0.01)
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 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.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():
output_dir = gr.Textbox()
config_path = gr.Textbox()
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()
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,
output_dir=output_dir,
config_path=config_path,
resume_btn=resume_btn,
progress_bar=progress_bar,
output_box=output_box,
loss_viewer=loss_viewer,
)
)
input_elems.update({output_dir, config_path})
output_elems = [output_box, progress_bar, loss_viewer]
cmd_preview_btn.click(engine.runner.preview_train, input_elems, output_elems, concurrency_limit=None)
arg_save_btn.click(engine.runner.save_args, input_elems, output_elems, concurrency_limit=None)
arg_load_btn.click(
engine.runner.load_args,
[engine.manager.get_elem_by_id("top.lang"), config_path],
list(input_elems) + [output_box],
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)
dataset_dir.change(list_dataset, [dataset_dir, training_stage], [dataset], queue=False)
training_stage.change(list_dataset, [dataset_dir, training_stage], [dataset], queue=False).then(
list_adapters,
[engine.manager.get_elem_by_id("top.model_name"), engine.manager.get_elem_by_id("top.finetuning_type")],
[reward_model],
queue=False,
).then(autoset_packing, [training_stage], [packing], queue=False)
return elem_dict
CSS = r"""
.duplicate-button {
margin: auto !important;
color: white !important;
background: black !important;
border-radius: 100vh !important;
}
.modal-box {
position: fixed !important;
top: 50%;
left: 50%;
transform: translate(-50%, -50%); /* center horizontally */
max-width: 1000px;
max-height: 750px;
overflow-y: auto;
background-color: var(--input-background-fill);
flex-wrap: nowrap !important;
border: 2px solid black !important;
z-index: 1000;
padding: 10px;
}
.dark .modal-box {
border: 2px solid white !important;
}
"""
from typing import TYPE_CHECKING, Any, Dict
from .chatter import WebChatModel
from .common import get_model_path, list_dataset, load_config
from .locales import LOCALES
from .manager import Manager
from .runner import Runner
from .utils import get_time
if TYPE_CHECKING:
from gradio.components import Component
class Engine:
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))
def _update_component(self, input_dict: Dict[str, Dict[str, Any]]) -> Dict["Component", "Component"]:
r"""
Gets the dict to update the components.
"""
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):
user_config = load_config() if not self.demo_mode else {}
lang = user_config.get("lang", None) or "en"
init_dict = {"top.lang": {"value": lang}, "infer.chat_box": {"visible": self.chatter.loaded}}
if not self.pure_chat:
init_dict["train.dataset"] = {"choices": list_dataset().choices}
init_dict["eval.dataset"] = {"choices": list_dataset().choices}
init_dict["train.output_dir"] = {"value": "train_{}".format(get_time())}
init_dict["train.config_path"] = {"value": "{}.yaml".format(get_time())}
init_dict["eval.output_dir"] = {"value": "eval_{}".format(get_time())}
init_dict["infer.image_box"] = {"visible": False}
if user_config.get("last_model", None):
init_dict["top.model_name"] = {"value": user_config["last_model"]}
init_dict["top.model_path"] = {"value": get_model_path(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):
return {
elem: elem.__class__(**LOCALES[elem_name][lang])
for elem_name, elem in self.manager.get_elem_iter()
if elem_name in LOCALES
}
import os
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_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)
with gr.Blocks(title="LLaMA Board", css=CSS) as demo:
if demo_mode:
gr.HTML("<h1><center>LLaMA Board: A One-stop Web UI for Getting Started with LLaMA Factory</center></h1>")
gr.HTML(
'<h3><center>Visit <a href="https://github.com/hiyouga/LLaMA-Factory" target="_blank">'
"LLaMA Factory</a> for details.</center></h3>"
)
gr.DuplicateButton(value="Duplicate Space for private use", elem_classes="duplicate-button")
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))
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)
with gr.Blocks(title="Web Demo", css=CSS) as demo:
lang = gr.Dropdown(choices=["en", "zh"])
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_share = os.environ.get("GRADIO_SHARE", "0").lower() in ["true", "1"]
server_name = os.environ.get("GRADIO_SERVER_NAME", "0.0.0.0")
create_ui().queue().launch(share=gradio_share, server_name=server_name, inbrowser=True)
def run_web_demo() -> None:
gradio_share = os.environ.get("GRADIO_SHARE", "0").lower() in ["true", "1"]
server_name = os.environ.get("GRADIO_SERVER_NAME", "0.0.0.0")
create_web_demo().queue().launch(share=gradio_share, server_name=server_name, inbrowser=True)
LOCALES = {
"lang": {
"en": {
"label": "Lang",
},
"ru": {
"label": "Русский",
},
"zh": {
"label": "语言",
},
},
"model_name": {
"en": {
"label": "Model name",
},
"ru": {
"label": "Название модели",
},
"zh": {
"label": "模型名称",
},
},
"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 的模型标识符。",
},
},
"finetuning_type": {
"en": {
"label": "Finetuning method",
},
"ru": {
"label": "Метод дообучения",
},
"zh": {
"label": "微调方法",
},
},
"adapter_path": {
"en": {
"label": "Adapter path",
},
"ru": {
"label": "Путь к адаптеру",
},
"zh": {
"label": "适配器路径",
},
},
"refresh_btn": {
"en": {
"value": "Refresh adapters",
},
"ru": {
"value": "Обновить адаптеры",
},
"zh": {
"value": "刷新适配器",
},
},
"advanced_tab": {
"en": {
"label": "Advanced configurations",
},
"ru": {
"label": "Расширенные конфигурации",
},
"zh": {
"label": "高级设置",
},
},
"quantization_bit": {
"en": {
"label": "Quantization bit",
"info": "Enable 4/8-bit model quantization (QLoRA).",
},
"ru": {
"label": "Уровень квантования",
"info": "Включить 4/8-битное квантование модели (QLoRA).",
},
"zh": {
"label": "量化等级",
"info": "启用 4/8 比特模型量化(QLoRA)。",
},
},
"template": {
"en": {
"label": "Prompt template",
"info": "The template used in constructing prompts.",
},
"ru": {
"label": "Шаблон запроса",
"info": "Шаблон, используемый при формировании запросов.",
},
"zh": {
"label": "提示模板",
"info": "构建提示词时使用的模板",
},
},
"rope_scaling": {
"en": {
"label": "RoPE scaling",
},
"ru": {
"label": "Масштабирование RoPE",
},
"zh": {
"label": "RoPE 插值方法",
},
},
"booster": {
"en": {
"label": "Booster",
},
"ru": {
"label": "Ускоритель",
},
"zh": {
"label": "加速方式",
},
},
"visual_inputs": {
"en": {
"label": "Visual inputs",
},
"ru": {
"label": "визуальные входы",
},
"zh": {
"label": "图像输入",
},
},
"training_stage": {
"en": {
"label": "Stage",
"info": "The stage to perform in training.",
},
"ru": {
"label": "Этап",
"info": "Этап выполнения обучения.",
},
"zh": {
"label": "训练阶段",
"info": "目前采用的训练方式。",
},
},
"dataset_dir": {
"en": {
"label": "Data dir",
"info": "Path to the data directory.",
},
"ru": {
"label": "Директория данных",
"info": "Путь к директории данных.",
},
"zh": {
"label": "数据路径",
"info": "数据文件夹的路径。",
},
},
"dataset": {
"en": {
"label": "Dataset",
},
"ru": {
"label": "Набор данных",
},
"zh": {
"label": "数据集",
},
},
"data_preview_btn": {
"en": {
"value": "Preview dataset",
},
"ru": {
"value": "Просмотреть набор данных",
},
"zh": {
"value": "预览数据集",
},
},
"preview_count": {
"en": {
"label": "Count",
},
"ru": {
"label": "Количество",
},
"zh": {
"label": "数量",
},
},
"page_index": {
"en": {
"label": "Page",
},
"ru": {
"label": "Страница",
},
"zh": {
"label": "页数",
},
},
"prev_btn": {
"en": {
"value": "Prev",
},
"ru": {
"value": "Предыдущая",
},
"zh": {
"value": "上一页",
},
},
"next_btn": {
"en": {
"value": "Next",
},
"ru": {
"value": "Следующая",
},
"zh": {
"value": "下一页",
},
},
"close_btn": {
"en": {
"value": "Close",
},
"ru": {
"value": "Закрыть",
},
"zh": {
"value": "关闭",
},
},
"preview_samples": {
"en": {
"label": "Samples",
},
"ru": {
"label": "Примеры",
},
"zh": {
"label": "样例",
},
},
"learning_rate": {
"en": {
"label": "Learning rate",
"info": "Initial learning rate for AdamW.",
},
"ru": {
"label": "Скорость обучения",
"info": "Начальная скорость обучения для AdamW.",
},
"zh": {
"label": "学习率",
"info": "AdamW 优化器的初始学习率。",
},
},
"num_train_epochs": {
"en": {
"label": "Epochs",
"info": "Total number of training epochs to perform.",
},
"ru": {
"label": "Эпохи",
"info": "Общее количество эпох обучения.",
},
"zh": {
"label": "训练轮数",
"info": "需要执行的训练总轮数。",
},
},
"max_grad_norm": {
"en": {
"label": "Maximum gradient norm",
"info": "Norm for gradient clipping.",
},
"ru": {
"label": "Максимальная норма градиента",
"info": "Норма для обрезки градиента.",
},
"zh": {
"label": "最大梯度范数",
"info": "用于梯度裁剪的范数。",
},
},
"max_samples": {
"en": {
"label": "Max samples",
"info": "Maximum samples per dataset.",
},
"ru": {
"label": "Максимальное количество образцов",
"info": "Максимальное количество образцов на набор данных.",
},
"zh": {
"label": "最大样本数",
"info": "每个数据集的最大样本数。",
},
},
"compute_type": {
"en": {
"label": "Compute type",
"info": "Whether to use mixed precision training.",
},
"ru": {
"label": "Тип вычислений",
"info": "Использовать ли обучение смешанной точности.",
},
"zh": {
"label": "计算类型",
"info": "是否使用混合精度训练。",
},
},
"cutoff_len": {
"en": {
"label": "Cutoff length",
"info": "Max tokens in input sequence.",
},
"ru": {
"label": "Длина обрезки",
"info": "Максимальное количество токенов во входной последовательности.",
},
"zh": {
"label": "截断长度",
"info": "输入序列分词后的最大长度。",
},
},
"batch_size": {
"en": {
"label": "Batch size",
"info": "Number of samples processed on each GPU.",
},
"ru": {
"label": "Размер пакета",
"info": "Количество образцов для обработки на каждом GPU.",
},
"zh": {
"label": "批处理大小",
"info": "每个 GPU 处理的样本数量。",
},
},
"gradient_accumulation_steps": {
"en": {
"label": "Gradient accumulation",
"info": "Number of steps for gradient accumulation.",
},
"ru": {
"label": "Накопление градиента",
"info": "Количество шагов накопления градиента.",
},
"zh": {
"label": "梯度累积",
"info": "梯度累积的步数。",
},
},
"val_size": {
"en": {
"label": "Val size",
"info": "Proportion of data in the dev set.",
},
"ru": {
"label": "Размер валидации",
"info": "Пропорция данных в наборе для разработки.",
},
"zh": {
"label": "验证集比例",
"info": "验证集占全部样本的百分比。",
},
},
"lr_scheduler_type": {
"en": {
"label": "LR scheduler",
"info": "Name of the learning rate scheduler.",
},
"ru": {
"label": "Планировщик скорости обучения",
"info": "Название планировщика скорости обучения.",
},
"zh": {
"label": "学习率调节器",
"info": "学习率调度器的名称。",
},
},
"extra_tab": {
"en": {
"label": "Extra configurations",
},
"ru": {
"label": "Дополнительные конфигурации",
},
"zh": {
"label": "其它参数设置",
},
},
"logging_steps": {
"en": {
"label": "Logging steps",
"info": "Number of steps between two logs.",
},
"ru": {
"label": "Шаги логирования",
"info": "Количество шагов между двумя записями в журнале.",
},
"zh": {
"label": "日志间隔",
"info": "每两次日志输出间的更新步数。",
},
},
"save_steps": {
"en": {
"label": "Save steps",
"info": "Number of steps between two checkpoints.",
},
"ru": {
"label": "Шаги сохранения",
"info": "Количество шагов между двумя контрольными точками.",
},
"zh": {
"label": "保存间隔",
"info": "每两次断点保存间的更新步数。",
},
},
"warmup_steps": {
"en": {
"label": "Warmup steps",
"info": "Number of steps used for warmup.",
},
"ru": {
"label": "Шаги прогрева",
"info": "Количество шагов, используемых для прогрева.",
},
"zh": {
"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": "嵌入向量所添加的噪声大小。",
},
},
"optim": {
"en": {
"label": "Optimizer",
"info": "The optimizer to use: adamw_torch, adamw_8bit or adafactor.",
},
"ru": {
"label": "Оптимизатор",
"info": "Оптимизатор для использования: adamw_torch, adamw_8bit или adafactor.",
},
"zh": {
"label": "优化器",
"info": "使用的优化器:adamw_torch、adamw_8bit 或 adafactor。",
},
},
"resize_vocab": {
"en": {
"label": "Resize token embeddings",
"info": "Resize the tokenizer vocab and the embedding layers.",
},
"ru": {
"label": "Изменение размера токенных эмбеддингов",
"info": "Изменить размер словаря токенизатора и слоев эмбеддинга.",
},
"zh": {
"label": "更改词表大小",
"info": "更改分词器词表和嵌入层的大小。",
},
},
"packing": {
"en": {
"label": "Pack sequences",
"info": "Pack sequences into samples of fixed length.",
},
"ru": {
"label": "Упаковка последовательностей",
"info": "Упаковка последовательностей в образцы фиксированной длины.",
},
"zh": {
"label": "序列打包",
"info": "将序列打包为等长样本。",
},
},
"upcast_layernorm": {
"en": {
"label": "Upcast LayerNorm",
"info": "Upcast weights of layernorm in float32.",
},
"ru": {
"label": "Приведение весов LayerNorm",
"info": "Приведение весов LayerNorm к float32.",
},
"zh": {
"label": "缩放归一化层",
"info": "将归一化层权重缩放至 32 位精度。",
},
},
"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": "仅训练块扩展后的参数。",
},
},
"shift_attn": {
"en": {
"label": "Enable S^2 Attention",
"info": "Use shift short attention proposed by LongLoRA.",
},
"ru": {
"label": "Включить S^2 внимание",
"info": "Использовать сдвиг внимания на короткие дистанции предложенный LongLoRA.",
},
"zh": {
"label": "使用 S^2 Attention",
"info": "使用 LongLoRA 提出的 shift short attention。",
},
},
"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 记录实验。",
},
},
"freeze_tab": {
"en": {
"label": "Freeze tuning configurations",
},
"ru": {
"label": "конфигурации для настройки заморозки",
},
"zh": {
"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": "最末尾(+)/最前端(-)可训练隐藏层的数量。",
},
},
"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": "可训练模块的名称。使用英文逗号分隔多个名称。",
},
},
"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": "除隐藏层以外的可训练模块名称。使用英文逗号分隔多个名称。",
},
},
"lora_tab": {
"en": {
"label": "LoRA configurations",
},
"ru": {
"label": "Конфигурации LoRA",
},
"zh": {
"label": "LoRA 参数设置",
},
},
"lora_rank": {
"en": {
"label": "LoRA rank",
"info": "The rank of LoRA matrices.",
},
"ru": {
"label": "Ранг матриц LoRA",
"info": "Ранг матриц LoRA.",
},
"zh": {
"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 缩放系数大小。",
},
},
"lora_dropout": {
"en": {
"label": "LoRA dropout",
"info": "Dropout ratio of LoRA weights.",
},
"ru": {
"label": "Вероятность отсева LoRA",
"info": "Вероятность отсева весов LoRA.",
},
"zh": {
"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 矩阵的学习率倍数。",
},
},
"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": "在现有的适配器上创建一个随机初始化后的新适配器。",
},
},
"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 层使用秩稳定缩放方法。",
},
},
"use_dora": {
"en": {
"label": "Use DoRA",
"info": "Use weight-decomposed LoRA.",
},
"ru": {
"label": "Используйте DoRA",
"info": "Используйте LoRA с декомпозицией весов.",
},
"zh": {
"label": "使用 DoRA",
"info": "使用权重分解的 LoRA。",
},
},
"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 的模块名称。使用英文逗号分隔多个名称。",
},
},
"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 层以外的可训练模块名称。使用英文逗号分隔多个名称。",
},
},
"rlhf_tab": {
"en": {
"label": "RLHF configurations",
},
"ru": {
"label": "Конфигурации RLHF",
},
"zh": {
"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 超参数大小。",
},
},
"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 损失的权重大小。",
},
},
"pref_loss": {
"en": {
"label": "Loss type",
"info": "The type of the loss function.",
},
"ru": {
"label": "Тип потерь",
"info": "Тип функции потерь.",
},
"zh": {
"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 训练中奖励模型的适配器路径。",
},
},
"ppo_score_norm": {
"en": {
"label": "Score norm",
"info": "Normalizing scores in PPO training.",
},
"ru": {
"label": "Норма оценок",
"info": "Нормализация оценок в тренировке PPO.",
},
"zh": {
"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 训练中将奖励分数做白化处理。",
},
},
"galore_tab": {
"en": {
"label": "GaLore configurations",
},
"ru": {
"label": "Конфигурации GaLore",
},
"zh": {
"label": "GaLore 参数设置",
},
},
"use_galore": {
"en": {
"label": "Use GaLore",
"info": "Enable gradient low-Rank projection.",
},
"ru": {
"label": "Использовать GaLore",
"info": "Включить проекцию градиента на низкоранговое пространство.",
},
"zh": {
"label": "使用 GaLore",
"info": "使用梯度低秩投影。",
},
},
"galore_rank": {
"en": {
"label": "GaLore rank",
"info": "The rank of GaLore gradients.",
},
"ru": {
"label": "Ранг GaLore",
"info": "Ранг градиентов GaLore.",
},
"zh": {
"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": "相邻两次投影更新的步数。",
},
},
"galore_scale": {
"en": {
"label": "GaLore scale",
"info": "GaLore scaling coefficient.",
},
"ru": {
"label": "LoRA Alpha",
"info": "Коэффициент масштабирования GaLore.",
},
"zh": {
"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 的模块名称。使用英文逗号分隔多个名称。",
},
},
"badam_tab": {
"en": {
"label": "BAdam configurations",
},
"ru": {
"label": "Конфигурации BAdam",
},
"zh": {
"label": "BAdam 参数设置",
},
},
"use_badam": {
"en": {
"label": "Use BAdam",
"info": "Enable the BAdam optimizer.",
},
"ru": {
"label": "Использовать BAdam",
"info": "Включите оптимизатор BAdam.",
},
"zh": {
"label": "使用 BAdam",
"info": "使用 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 优化器。",
},
},
"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 优化器的块切换策略。",
},
},
"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 优化器的块切换频率。",
},
},
"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 优化器的更新比例。",
},
},
"cmd_preview_btn": {
"en": {
"value": "Preview command",
},
"ru": {
"value": "Просмотр команды",
},
"zh": {
"value": "预览命令",
},
},
"arg_save_btn": {
"en": {
"value": "Save arguments",
},
"ru": {
"value": "Сохранить аргументы",
},
"zh": {
"value": "保存训练参数",
},
},
"arg_load_btn": {
"en": {
"value": "Load arguments",
},
"ru": {
"value": "Загрузить аргументы",
},
"zh": {
"value": "载入训练参数",
},
},
"start_btn": {
"en": {
"value": "Start",
},
"ru": {
"value": "Начать",
},
"zh": {
"value": "开始",
},
},
"stop_btn": {
"en": {
"value": "Abort",
},
"ru": {
"value": "Прервать",
},
"zh": {
"value": "中断",
},
},
"output_dir": {
"en": {
"label": "Output dir",
"info": "Directory for saving results.",
},
"ru": {
"label": "Выходной каталог",
"info": "Каталог для сохранения результатов.",
},
"zh": {
"label": "输出目录",
"info": "保存结果的路径。",
},
},
"config_path": {
"en": {
"label": "Config path",
"info": "Path to config saving arguments.",
},
"ru": {
"label": "Путь к конфигурации",
"info": "Путь для сохранения аргументов конфигурации.",
},
"zh": {
"label": "配置路径",
"info": "保存训练参数的配置文件路径。",
},
},
"output_box": {
"en": {
"value": "Ready.",
},
"ru": {
"value": "Готово.",
},
"zh": {
"value": "准备就绪。",
},
},
"loss_viewer": {
"en": {
"label": "Loss",
},
"ru": {
"label": "Потери",
},
"zh": {
"label": "损失",
},
},
"predict": {
"en": {
"label": "Save predictions",
},
"ru": {
"label": "Сохранить предсказания",
},
"zh": {
"label": "保存预测结果",
},
},
"infer_backend": {
"en": {
"label": "Inference engine",
},
"ru": {
"label": "Инференс движок",
},
"zh": {
"label": "推理引擎",
},
},
"load_btn": {
"en": {
"value": "Load model",
},
"ru": {
"value": "Загрузить модель",
},
"zh": {
"value": "加载模型",
},
},
"unload_btn": {
"en": {
"value": "Unload model",
},
"ru": {
"value": "Выгрузить модель",
},
"zh": {
"value": "卸载模型",
},
},
"info_box": {
"en": {
"value": "Model unloaded, please load a model first.",
},
"ru": {
"value": "Модель не загружена, загрузите модель сначала.",
},
"zh": {
"value": "模型未加载,请先加载模型。",
},
},
"role": {
"en": {
"label": "Role",
},
"ru": {
"label": "Роль",
},
"zh": {
"label": "角色",
},
},
"system": {
"en": {
"placeholder": "System prompt (optional)",
},
"ru": {
"placeholder": "Системный запрос (по желанию)",
},
"zh": {
"placeholder": "系统提示词(非必填)",
},
},
"tools": {
"en": {
"placeholder": "Tools (optional)",
},
"ru": {
"placeholder": "Инструменты (по желанию)",
},
"zh": {
"placeholder": "工具列表(非必填)",
},
},
"image": {
"en": {
"label": "Image (optional)",
},
"ru": {
"label": "Изображение (по желанию)",
},
"zh": {
"label": "图像(非必填)",
},
},
"query": {
"en": {
"placeholder": "Input...",
},
"ru": {
"placeholder": "Ввод...",
},
"zh": {
"placeholder": "输入...",
},
},
"submit_btn": {
"en": {
"value": "Submit",
},
"ru": {
"value": "Отправить",
},
"zh": {
"value": "提交",
},
},
"max_length": {
"en": {
"label": "Maximum length",
},
"ru": {
"label": "Максимальная длина",
},
"zh": {
"label": "最大长度",
},
},
"max_new_tokens": {
"en": {
"label": "Maximum new tokens",
},
"ru": {
"label": "Максимальное количество новых токенов",
},
"zh": {
"label": "最大生成长度",
},
},
"top_p": {
"en": {
"label": "Top-p",
},
"ru": {
"label": "Лучшие-p",
},
"zh": {
"label": "Top-p 采样值",
},
},
"temperature": {
"en": {
"label": "Temperature",
},
"ru": {
"label": "Температура",
},
"zh": {
"label": "温度系数",
},
},
"clear_btn": {
"en": {
"value": "Clear history",
},
"ru": {
"value": "Очистить историю",
},
"zh": {
"value": "清空历史",
},
},
"export_size": {
"en": {
"label": "Max shard size (GB)",
"info": "The maximum size for a model file.",
},
"ru": {
"label": "Максимальный размер фрагмента (ГБ)",
"info": "Максимальный размер файла модели.",
},
"zh": {
"label": "最大分块大小(GB)",
"info": "单个模型文件的最大大小。",
},
},
"export_quantization_bit": {
"en": {
"label": "Export quantization bit.",
"info": "Quantizing the exported model.",
},
"ru": {
"label": "Экспорт бита квантования",
"info": "Квантование экспортируемой модели.",
},
"zh": {
"label": "导出量化等级",
"info": "量化导出模型。",
},
},
"export_quantization_dataset": {
"en": {
"label": "Export quantization dataset",
"info": "The calibration dataset used for quantization.",
},
"ru": {
"label": "Экспорт набора данных для квантования",
"info": "Набор данных калибровки, используемый для квантования.",
},
"zh": {
"label": "导出量化数据集",
"info": "量化过程中使用的校准数据集。",
},
},
"export_device": {
"en": {
"label": "Export device",
"info": "Which device should be used to export model.",
},
"ru": {
"label": "Экспорт устройство",
"info": "Какое устройство следует использовать для экспорта модели.",
},
"zh": {
"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 格式保存模型。",
},
},
"export_dir": {
"en": {
"label": "Export dir",
"info": "Directory to save exported model.",
},
"ru": {
"label": "Каталог экспорта",
"info": "Каталог для сохранения экспортированной модели.",
},
"zh": {
"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。",
},
},
"export_btn": {
"en": {
"value": "Export",
},
"ru": {
"value": "Экспорт",
},
"zh": {
"value": "开始导出",
},
},
}
ALERTS = {
"err_conflict": {
"en": "A process is in running, please abort it first.",
"ru": "Процесс уже запущен, пожалуйста, сначала прервите его.",
"zh": "任务已存在,请先中断训练。",
},
"err_exists": {
"en": "You have loaded a model, please unload it first.",
"ru": "Вы загрузили модель, сначала разгрузите ее.",
"zh": "模型已存在,请先卸载模型。",
},
"err_no_model": {
"en": "Please select a model.",
"ru": "Пожалуйста, выберите модель.",
"zh": "请选择模型。",
},
"err_no_path": {
"en": "Model not found.",
"ru": "Модель не найдена.",
"zh": "模型未找到。",
},
"err_no_dataset": {
"en": "Please choose a dataset.",
"ru": "Пожалуйста, выберите набор данных.",
"zh": "请选择数据集。",
},
"err_no_adapter": {
"en": "Please select an adapter.",
"ru": "Пожалуйста, выберите адаптер.",
"zh": "请选择适配器。",
},
"err_no_reward_model": {
"en": "Please select a reward model.",
"ru": "Пожалуйста, выберите модель вознаграждения.",
"zh": "请选择奖励模型。",
},
"err_no_export_dir": {
"en": "Please provide export dir.",
"ru": "Пожалуйста, укажите каталог для экспорта.",
"zh": "请填写导出目录。",
},
"err_gptq_lora": {
"en": "Please merge adapters before quantizing the model.",
"ru": "Пожалуйста, объедините адаптеры перед квантованием модели.",
"zh": "量化模型前请先合并适配器。",
},
"err_failed": {
"en": "Failed.",
"ru": "Ошибка.",
"zh": "训练出错。",
},
"err_demo": {
"en": "Training is unavailable in demo mode, duplicate the space to a private one first.",
"ru": "Обучение недоступно в демонстрационном режиме, сначала скопируйте пространство в частное.",
"zh": "展示模式不支持训练,请先复制到私人空间。",
},
"err_device_count": {
"en": "Multiple GPUs are not supported yet.",
"ru": "Пока не поддерживается множественные GPU.",
"zh": "尚不支持多 GPU 训练。",
},
"err_tool_name": {
"en": "Tool name not found.",
"ru": "Имя инструмента не найдено.",
"zh": "工具名称未找到。",
},
"err_json_schema": {
"en": "Invalid JSON schema.",
"ru": "Неверная схема JSON.",
"zh": "Json 格式错误。",
},
"err_config_not_found": {
"en": "Config file is not found.",
"ru": "Файл конфигурации не найден.",
"zh": "未找到配置文件。",
},
"warn_no_cuda": {
"en": "CUDA environment was not detected.",
"ru": "Среда CUDA не обнаружена.",
"zh": "未检测到 CUDA 环境。",
},
"info_aborting": {
"en": "Aborted, wait for terminating...",
"ru": "Прервано, ожидание завершения...",
"zh": "训练中断,正在等待进程结束……",
},
"info_aborted": {
"en": "Ready.",
"ru": "Готово.",
"zh": "准备就绪。",
},
"info_finished": {
"en": "Finished.",
"ru": "Завершено.",
"zh": "训练完毕。",
},
"info_config_saved": {
"en": "Arguments have been saved at: ",
"ru": "Аргументы были сохранены по адресу: ",
"zh": "训练参数已保存至:",
},
"info_config_loaded": {
"en": "Arguments have been restored.",
"ru": "Аргументы были восстановлены.",
"zh": "训练参数已载入。",
},
"info_loading": {
"en": "Loading model...",
"ru": "Загрузка модели...",
"zh": "加载中……",
},
"info_unloading": {
"en": "Unloading model...",
"ru": "Выгрузка модели...",
"zh": "卸载中……",
},
"info_loaded": {
"en": "Model loaded, now you can chat with your model!",
"ru": "Модель загружена, теперь вы можете общаться с вашей моделью!",
"zh": "模型已加载,可以开始聊天了!",
},
"info_unloaded": {
"en": "Model unloaded.",
"ru": "Модель выгружена.",
"zh": "模型已卸载。",
},
"info_exporting": {
"en": "Exporting model...",
"ru": "Экспорт модели...",
"zh": "正在导出模型……",
},
"info_exported": {
"en": "Model exported.",
"ru": "Модель экспортирована.",
"zh": "模型导出完成。",
},
}
from typing import TYPE_CHECKING, Dict, Generator, List, Set, Tuple
if TYPE_CHECKING:
from gradio.components import Component
class Manager:
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"""
Adds elements to manager.
"""
for elem_name, elem in elem_dict.items():
elem_id = "{}.{}".format(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"""
Returns the list of all elements.
"""
return list(self._id_to_elem.values())
def get_elem_iter(self) -> Generator[Tuple[str, "Component"], None, None]:
r"""
Returns 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"""
Gets 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"""
Gets id by element.
"""
return self._elem_to_id[elem]
def get_base_elems(self) -> Set["Component"]:
r"""
Gets 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.adapter_path"],
self._id_to_elem["top.quantization_bit"],
self._id_to_elem["top.template"],
self._id_to_elem["top.rope_scaling"],
self._id_to_elem["top.booster"],
self._id_to_elem["top.visual_inputs"],
}
import os
import signal
from copy import deepcopy
from subprocess import Popen, TimeoutExpired
from typing import TYPE_CHECKING, Any, Dict, Generator, Optional
import psutil
from transformers.trainer import TRAINING_ARGS_NAME
from transformers.utils import is_torch_cuda_available
from ..extras.constants import TRAINING_STAGES
from ..extras.misc import get_device_count, torch_gc
from ..extras.packages import is_gradio_available
from .common import get_module, get_save_dir, load_args, load_config, save_args
from .locales import ALERTS
from .utils import gen_cmd, get_eval_results, get_trainer_info, save_cmd
if is_gradio_available():
import gradio as gr
if TYPE_CHECKING:
from gradio.components import Component
from .manager import Manager
class Runner:
def __init__(self, manager: "Manager", demo_mode: bool = False) -> None:
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:
for children in psutil.Process(self.trainer.pid).children(): # abort the child process
os.kill(children.pid, signal.SIGABRT)
def _initialize(self, data: Dict["Component", Any], do_train: bool, from_preview: bool) -> str:
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 not from_preview and get_device_count() > 1:
return ALERTS["err_device_count"][lang]
if do_train:
stage = TRAINING_STAGES[get("train.training_stage")]
reward_model = get("train.reward_model")
if stage == "ppo" and not reward_model:
return ALERTS["err_no_reward_model"][lang]
if not from_preview and not is_torch_cuda_available():
gr.Warning(ALERTS["warn_no_cuda"][lang])
return ""
def _finalize(self, lang: str, finish_info: str) -> str:
finish_info = ALERTS["info_aborted"][lang] if self.aborted else finish_info
self.trainer = None
self.aborted = False
self.running = False
self.running_data = None
torch_gc()
return finish_info
def _parse_train_args(self, data: Dict["Component", Any]) -> Dict[str, Any]:
get = lambda elem_id: data[self.manager.get_elem_by_id(elem_id)]
user_config = load_config()
if get("top.adapter_path"):
adapter_name_or_path = ",".join(
[
get_save_dir(get("top.model_name"), get("top.finetuning_type"), adapter)
for adapter in get("top.adapter_path")
]
)
else:
adapter_name_or_path = None
args = dict(
stage=TRAINING_STAGES[get("train.training_stage")],
do_train=True,
model_name_or_path=get("top.model_path"),
adapter_name_or_path=adapter_name_or_path,
cache_dir=user_config.get("cache_dir", None),
preprocessing_num_workers=16,
finetuning_type=get("top.finetuning_type"),
quantization_bit=int(get("top.quantization_bit")) if get("top.quantization_bit") in ["8", "4"] else None,
template=get("top.template"),
rope_scaling=get("top.rope_scaling") if get("top.rope_scaling") in ["linear", "dynamic"] else None,
flash_attn="fa2" if get("top.booster") == "flashattn2" else "auto",
use_unsloth=(get("top.booster") == "unsloth"),
visual_inputs=get("top.visual_inputs"),
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,
optim=get("train.optim"),
resize_vocab=get("train.resize_vocab"),
packing=get("train.packing"),
upcast_layernorm=get("train.upcast_layernorm"),
use_llama_pro=get("train.use_llama_pro"),
shift_attn=get("train.shift_attn"),
report_to="all" if get("train.report_to") else "none",
use_galore=get("train.use_galore"),
use_badam=get("train.use_badam"),
output_dir=get_save_dir(get("top.model_name"), get("top.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,
)
# 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["lora_target"] = get("train.lora_target") or get_module(get("top.model_name"))
args["additional_target"] = get("train.additional_target") or None
if args["use_llama_pro"]:
args["num_layer_trainable"] = get("train.num_layer_trainable")
# rlhf config
if args["stage"] == "ppo":
args["reward_model"] = ",".join(
[
get_save_dir(get("top.model_name"), get("top.finetuning_type"), adapter)
for adapter in get("train.reward_model")
]
)
args["reward_model_type"] = "lora" if args["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"] == "dpo":
args["dpo_beta"] = get("train.pref_beta")
args["dpo_ftx"] = get("train.pref_ftx")
args["dpo_loss"] = get("train.pref_loss")
elif args["stage"] == "kto":
args["kto_beta"] = get("train.pref_beta")
args["kto_ftx"] = get("train.pref_ftx")
elif args["stage"] == "orpo":
args["orpo_beta"] = get("train.pref_beta")
# 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")
# 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")
# eval config
if get("train.val_size") > 1e-6 and args["stage"] != "ppo":
args["val_size"] = get("train.val_size")
args["evaluation_strategy"] = "steps"
args["eval_steps"] = args["save_steps"]
args["per_device_eval_batch_size"] = args["per_device_train_batch_size"]
return args
def _parse_eval_args(self, data: Dict["Component", Any]) -> Dict[str, Any]:
get = lambda elem_id: data[self.manager.get_elem_by_id(elem_id)]
user_config = load_config()
if get("top.adapter_path"):
adapter_name_or_path = ",".join(
[
get_save_dir(get("top.model_name"), get("top.finetuning_type"), adapter)
for adapter in get("top.adapter_path")
]
)
else:
adapter_name_or_path = None
args = dict(
stage="sft",
model_name_or_path=get("top.model_path"),
adapter_name_or_path=adapter_name_or_path,
cache_dir=user_config.get("cache_dir", None),
preprocessing_num_workers=16,
finetuning_type=get("top.finetuning_type"),
quantization_bit=int(get("top.quantization_bit")) if get("top.quantization_bit") in ["8", "4"] else None,
template=get("top.template"),
rope_scaling=get("top.rope_scaling") if get("top.rope_scaling") in ["linear", "dynamic"] else None,
flash_attn="fa2" if get("top.booster") == "flashattn2" else "auto",
use_unsloth=(get("top.booster") == "unsloth"),
visual_inputs=get("top.visual_inputs"),
dataset_dir=get("eval.dataset_dir"),
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,
max_new_tokens=get("eval.max_new_tokens"),
top_p=get("eval.top_p"),
temperature=get("eval.temperature"),
output_dir=get_save_dir(get("top.model_name"), get("top.finetuning_type"), get("eval.output_dir")),
)
if get("eval.predict"):
args["do_predict"] = True
else:
args["do_eval"] = True
return args
def _preview(self, data: Dict["Component", Any], do_train: bool) -> Generator[Dict["Component", str], None, None]:
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]:
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)
env = deepcopy(os.environ)
env["CUDA_VISIBLE_DEVICES"] = os.environ.get("CUDA_VISIBLE_DEVICES", "0")
env["LLAMABOARD_ENABLED"] = "1"
self.trainer = Popen("llamafactory-cli train {}".format(save_cmd(args)), env=env, shell=True)
yield from self.monitor()
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):
self.aborted = False
self.running = True
get = lambda elem_id: self.running_data[self.manager.get_elem_by_id(elem_id)]
lang = get("top.lang")
model_name = get("top.model_name")
finetuning_type = 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
while self.trainer is not None:
if self.aborted:
yield {
output_box: ALERTS["info_aborting"][lang],
progress_bar: gr.Slider(visible=False),
}
else:
running_log, running_progress, running_loss = get_trainer_info(output_path, self.do_train)
return_dict = {
output_box: running_log,
progress_bar: running_progress,
}
if running_loss is not None:
return_dict[loss_viewer] = running_loss
yield return_dict
try:
self.trainer.wait(2)
self.trainer = None
except TimeoutExpired:
continue
if self.do_train:
if os.path.exists(os.path.join(output_path, TRAINING_ARGS_NAME)):
finish_info = ALERTS["info_finished"][lang]
else:
finish_info = ALERTS["err_failed"][lang]
else:
if os.path.exists(os.path.join(output_path, "all_results.json")):
finish_info = get_eval_results(os.path.join(output_path, "all_results.json"))
else:
finish_info = ALERTS["err_failed"][lang]
return_dict = {
output_box: self._finalize(lang, finish_info),
progress_bar: gr.Slider(visible=False),
}
yield return_dict
def save_args(self, data: dict):
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}
config_dict: Dict[str, Any] = {}
lang = data[self.manager.get_elem_by_id("top.lang")]
config_path = data[self.manager.get_elem_by_id("train.config_path")]
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
save_path = save_args(config_path, config_dict)
return {output_box: ALERTS["info_config_saved"][lang] + save_path}
def load_args(self, lang: str, config_path: str):
output_box = self.manager.get_elem_by_id("train.output_box")
config_dict = load_args(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
import json
import os
from datetime import datetime
from typing import Any, Dict, List, Optional, Tuple
from yaml import safe_dump
from ..extras.constants import RUNNING_LOG, TRAINER_CONFIG, TRAINER_LOG
from ..extras.packages import is_gradio_available, is_matplotlib_available
from ..extras.ploting import gen_loss_plot
from .locales import ALERTS
if is_gradio_available():
import gradio as gr
def can_quantize(finetuning_type: str) -> "gr.Dropdown":
if finetuning_type != "lora":
return gr.Dropdown(value="none", interactive=False)
else:
return gr.Dropdown(interactive=True)
def check_json_schema(text: str, lang: str) -> None:
try:
tools = json.loads(text)
if tools:
assert isinstance(tools, list)
for tool in tools:
if "name" not in tool:
raise NotImplementedError("Name not found.")
except NotImplementedError:
gr.Warning(ALERTS["err_tool_name"][lang])
except Exception:
gr.Warning(ALERTS["err_json_schema"][lang])
def clean_cmd(args: Dict[str, Any]) -> Dict[str, Any]:
no_skip_keys = ["packing"]
return {k: v for k, v in args.items() if (k in no_skip_keys) or (v is not None and v is not False and v != "")}
def gen_cmd(args: Dict[str, Any]) -> str:
current_devices = os.environ.get("CUDA_VISIBLE_DEVICES", "0")
cmd_lines = ["CUDA_VISIBLE_DEVICES={} llamafactory-cli train ".format(current_devices)]
for k, v in clean_cmd(args).items():
cmd_lines.append(" --{} {} ".format(k, str(v)))
cmd_text = "\\\n".join(cmd_lines)
cmd_text = "```bash\n{}\n```".format(cmd_text)
return cmd_text
def get_eval_results(path: os.PathLike) -> str:
with open(path, "r", encoding="utf-8") as f:
result = json.dumps(json.load(f), indent=4)
return "```json\n{}\n```\n".format(result)
def get_time() -> str:
return datetime.now().strftime(r"%Y-%m-%d-%H-%M-%S")
def get_trainer_info(output_path: os.PathLike, do_train: bool) -> Tuple[str, "gr.Slider", Optional["gr.Plot"]]:
running_log = ""
running_progress = gr.Slider(visible=False)
running_loss = None
running_log_path = os.path.join(output_path, RUNNING_LOG)
if os.path.isfile(running_log_path):
with open(running_log_path, "r", encoding="utf-8") as f:
running_log = f.read()
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, "r", 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_loss = gr.Plot(gen_loss_plot(trainer_log))
return running_log, running_progress, running_loss
def save_cmd(args: Dict[str, Any]) -> str:
output_dir = args["output_dir"]
os.makedirs(output_dir, exist_ok=True)
with open(os.path.join(output_dir, TRAINER_CONFIG), "w", encoding="utf-8") as f:
safe_dump(clean_cmd(args), f)
return os.path.join(output_dir, TRAINER_CONFIG)
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()
import os
from llamafactory.webui.interface import create_ui
def main():
gradio_share = os.environ.get("GRADIO_SHARE", "0").lower() in ["true", "1"]
server_name = os.environ.get("GRADIO_SERVER_NAME", "0.0.0.0")
create_ui().queue().launch(share=gradio_share, server_name=server_name, inbrowser=True)
if __name__ == "__main__":
main()
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
tokenizer = AutoTokenizer.from_pretrained("./internlm2-math-7b", trust_remote_code=True)
# Set `torch_dtype=torch.float16` to load model in float16, otherwise it will be loaded as float32 and might cause OOM Error.
model = AutoModelForCausalLM.from_pretrained("./internlm2-math-7b", trust_remote_code=True, torch_dtype=torch.float16).cuda()
model = model.eval()
response, history = model.chat(tokenizer, "1+1=", history=[], meta_instruction="")
print(response)
# 模型唯一标识
modelCode=
# 模型名称
modelName=internlm2-math-7b
# 模型描述
modelDescription=InternLM-Math是基于InternLM2-Base模型进行数学预训练得到的大型语言模型,是首个同时支持形式化数学语言及解题过程评价的开源模型 ,以强大内生计算和推理能力,为技术社区提供强大数学工具和模型范式。
# 应用场景
appScenario=推理,训练,对话问答,科研,教育,政府,金融
# 框架类型
frameType=Pytorch
File added
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment