mirror of
https://github.com/hiyouga/LLaMA-Factory.git
synced 2026-10-17 04:15:51 +08:00
Compare commits
4 Commits
a61cfa692a
...
76a0391ddd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
76a0391ddd | ||
|
|
445163ab5e | ||
|
|
d58ec6a0bc | ||
|
|
5987a8dd68 |
@@ -40,7 +40,7 @@ dependencies = [
|
||||
"torch>=2.4.0",
|
||||
"torchvision>=0.19.0",
|
||||
"torchaudio>=2.4.0",
|
||||
"transformers>=4.55.0,<=5.6.0,!=4.57.0",
|
||||
"transformers>=4.55.0,<=5.7.0,!=4.57.0,!=5.6.0",
|
||||
"datasets>=2.16.0,<=4.0.0",
|
||||
"accelerate>=1.3.0,<=1.11.0",
|
||||
"peft>=0.18.0,<=0.18.1",
|
||||
|
||||
@@ -19,7 +19,7 @@ from threading import Thread
|
||||
from typing import TYPE_CHECKING, Any, Optional, Union
|
||||
|
||||
import torch
|
||||
from transformers import GenerationConfig, TextIteratorStreamer
|
||||
from transformers import GenerationConfig, TextIteratorStreamer, set_seed
|
||||
from typing_extensions import override
|
||||
|
||||
from ..data import get_template_and_fix_tokenizer
|
||||
@@ -128,6 +128,7 @@ class HuggingfaceEngine(BaseEngine):
|
||||
skip_special_tokens: Optional[bool] = input_kwargs.pop("skip_special_tokens", None)
|
||||
max_length: Optional[int] = input_kwargs.pop("max_length", None)
|
||||
max_new_tokens: Optional[int] = input_kwargs.pop("max_new_tokens", None)
|
||||
seed: Optional[int] = input_kwargs.pop("seed", None)
|
||||
stop: Optional[Union[str, list[str]]] = input_kwargs.pop("stop", None)
|
||||
|
||||
if stop is not None:
|
||||
@@ -177,6 +178,8 @@ class HuggingfaceEngine(BaseEngine):
|
||||
attention_mask=attention_mask,
|
||||
generation_config=GenerationConfig(**generating_args),
|
||||
)
|
||||
if seed is not None:
|
||||
gen_kwargs["_seed"] = seed
|
||||
|
||||
mm_inputs = template.mm_plugin.get_mm_inputs(**mm_input_dict, batch_ids=[prompt_ids], processor=processor)
|
||||
for key, value in mm_inputs.items():
|
||||
@@ -237,6 +240,10 @@ class HuggingfaceEngine(BaseEngine):
|
||||
audios,
|
||||
input_kwargs,
|
||||
)
|
||||
seed = gen_kwargs.pop("_seed", None)
|
||||
if seed is not None:
|
||||
set_seed(seed)
|
||||
|
||||
generate_output = model.generate(**gen_kwargs)
|
||||
if isinstance(generate_output, tuple):
|
||||
generate_output = generate_output[1][0] # post-process the minicpm_o output
|
||||
@@ -292,6 +299,10 @@ class HuggingfaceEngine(BaseEngine):
|
||||
audios,
|
||||
input_kwargs,
|
||||
)
|
||||
seed = gen_kwargs.pop("_seed", None)
|
||||
if seed is not None:
|
||||
set_seed(seed)
|
||||
|
||||
streamer = TextIteratorStreamer(
|
||||
tokenizer,
|
||||
skip_prompt=True,
|
||||
|
||||
@@ -171,6 +171,7 @@ class SGLangEngine(BaseEngine):
|
||||
skip_special_tokens: Optional[bool] = input_kwargs.pop("skip_special_tokens", None)
|
||||
max_length: Optional[int] = input_kwargs.pop("max_length", None)
|
||||
max_new_tokens: Optional[int] = input_kwargs.pop("max_new_tokens", None)
|
||||
seed: Optional[int] = input_kwargs.pop("seed", None)
|
||||
stop: Optional[Union[str, list[str]]] = input_kwargs.pop("stop", None)
|
||||
|
||||
if num_return_sequences != 1:
|
||||
@@ -205,6 +206,8 @@ class SGLangEngine(BaseEngine):
|
||||
if skip_special_tokens is not None
|
||||
else self.generating_args["skip_special_tokens"],
|
||||
}
|
||||
if seed is not None:
|
||||
sampling_params["seed"] = seed
|
||||
|
||||
def stream_request():
|
||||
json_data = {
|
||||
|
||||
@@ -144,6 +144,7 @@ class VllmEngine(BaseEngine):
|
||||
skip_special_tokens: Optional[bool] = input_kwargs.pop("skip_special_tokens", None)
|
||||
max_length: Optional[int] = input_kwargs.pop("max_length", None)
|
||||
max_new_tokens: Optional[int] = input_kwargs.pop("max_new_tokens", None)
|
||||
seed: Optional[int] = input_kwargs.pop("seed", None)
|
||||
stop: Optional[Union[str, list[str]]] = input_kwargs.pop("stop", None)
|
||||
|
||||
if length_penalty is not None:
|
||||
@@ -163,7 +164,7 @@ class VllmEngine(BaseEngine):
|
||||
if max_new_tokens:
|
||||
max_tokens = max_new_tokens
|
||||
|
||||
sampling_params = SamplingParams(
|
||||
sampling_kwargs = dict(
|
||||
n=num_return_sequences,
|
||||
repetition_penalty=(
|
||||
repetition_penalty if repetition_penalty is not None else self.generating_args["repetition_penalty"]
|
||||
@@ -179,6 +180,10 @@ class VllmEngine(BaseEngine):
|
||||
if skip_special_tokens is not None
|
||||
else self.generating_args["skip_special_tokens"],
|
||||
)
|
||||
if seed is not None:
|
||||
sampling_kwargs["seed"] = seed
|
||||
|
||||
sampling_params = SamplingParams(**sampling_kwargs)
|
||||
|
||||
multi_modal_data = {}
|
||||
if images is not None: # add image features
|
||||
|
||||
@@ -929,7 +929,7 @@ class InternVLPlugin(BasePlugin):
|
||||
messages = deepcopy(messages)
|
||||
mm_inputs = self._get_mm_inputs(images, videos, audios, processor)
|
||||
|
||||
image_pixel_patch_list = mm_inputs.get("image_num_patches") # pathes of images
|
||||
image_pixel_patch_list = mm_inputs.get("image_num_patches") # patches of images
|
||||
video_num_patches = mm_inputs.get("video_num_patches") # all patches for frames of videos
|
||||
video_patch_indices = mm_inputs.get("video_patch_indices") # num frames of per video
|
||||
|
||||
@@ -2667,7 +2667,7 @@ class Qwen2OmniPlugin(Qwen2VLPlugin):
|
||||
|
||||
if (
|
||||
use_audio_in_video and len(audios) and len(videos)
|
||||
): # if use the audio of video # deal video token and audio token togather
|
||||
): # if use the audio of video # deal video token and audio token together
|
||||
if len(videos) != len(audios):
|
||||
raise ValueError(
|
||||
f"Number of videos ({len(videos)}) must match number of audios ({len(audios)}) when using audio in video."
|
||||
|
||||
@@ -1035,7 +1035,7 @@ register_template(
|
||||
format_assistant=StringFormatter(slots=["{{content}}<turn|>\n"]),
|
||||
format_system=StringFormatter(
|
||||
slots=["<|turn>system\n<|think|>{{content}}<turn|>\n"]
|
||||
), # default thought singal contained
|
||||
), # default thought signal contained
|
||||
format_observation=StringFormatter(
|
||||
slots=["<|turn>tool\n{{content}}<turn|>\n<|turn>model\n"]
|
||||
), # seem not consistent with the chattemplate
|
||||
@@ -1061,7 +1061,7 @@ register_template(
|
||||
format_assistant=StringFormatter(slots=["{{content}}<turn|>\n"]),
|
||||
format_system=StringFormatter(
|
||||
slots=["<|turn>system\n<|think|>{{content}}<turn|>\n"]
|
||||
), # default thought singal contained
|
||||
), # default thought signal contained
|
||||
format_observation=StringFormatter(slots=["<|turn>tool\n{{content}}<turn|>\n<|turn>model\n"]),
|
||||
format_tools=ToolFormatter(tool_format="gemma4"),
|
||||
format_function=FunctionFormatter(slots=["<|tool>{{content}}<tool|>"], tool_format="gemma4"),
|
||||
|
||||
@@ -94,7 +94,9 @@ def check_version(requirement: str, mandatory: bool = False) -> None:
|
||||
|
||||
def check_dependencies() -> None:
|
||||
r"""Check the version of the required packages."""
|
||||
check_version("transformers>=4.55.0,<=5.6.0")
|
||||
check_version("transformers>=4.55.0,<=5.7.0")
|
||||
check_version("transformers!=4.57.0")
|
||||
check_version("transformers!=5.6.0")
|
||||
check_version("datasets>=2.16.0,<=4.0.0")
|
||||
check_version("accelerate>=1.3.0,<=1.15.0")
|
||||
check_version("peft>=0.18.0,<=0.20.0")
|
||||
|
||||
@@ -44,7 +44,7 @@ class EvaluationArguments:
|
||||
)
|
||||
n_shot: int = field(
|
||||
default=5,
|
||||
metadata={"help": "Number of examplars for few-shot learning."},
|
||||
metadata={"help": "Number of exemplars for few-shot learning."},
|
||||
)
|
||||
save_dir: str | None = field(
|
||||
default=None,
|
||||
|
||||
@@ -385,7 +385,7 @@ class BAdamArgument:
|
||||
"help": (
|
||||
"The mode of the mask for BAdam optimizer. "
|
||||
"`adjacent` means that the trainable parameters are adjacent to each other, "
|
||||
"`scatter` means that trainable parameters are randomly choosed from the weight."
|
||||
"`scatter` means that trainable parameters are randomly chosen from the weight."
|
||||
)
|
||||
},
|
||||
)
|
||||
@@ -530,7 +530,7 @@ class FinetuningArguments(
|
||||
)
|
||||
freeze_vision_tower: bool = field(
|
||||
default=True,
|
||||
metadata={"help": "Whether ot not to freeze the vision tower in MLLM training."},
|
||||
metadata={"help": "Whether or not to freeze the vision tower in MLLM training."},
|
||||
)
|
||||
freeze_multi_modal_projector: bool = field(
|
||||
default=True,
|
||||
|
||||
@@ -134,7 +134,7 @@ def _training_function(config: dict[str, Any]) -> None:
|
||||
raise ValueError(f"Unknown task: {finetuning_args.stage}.")
|
||||
|
||||
if is_ray_available() and ray.is_initialized():
|
||||
return # if ray is intialized it will destroy the process group on return
|
||||
return # if ray is initialized it will destroy the process group on return
|
||||
|
||||
try:
|
||||
if dist.is_initialized():
|
||||
|
||||
@@ -203,6 +203,7 @@ class WebChatModel(ChatModel):
|
||||
max_new_tokens: int,
|
||||
top_p: float,
|
||||
temperature: float,
|
||||
seed: float | int,
|
||||
skip_special_tokens: bool,
|
||||
escape_html: bool,
|
||||
enable_thinking: bool,
|
||||
@@ -225,6 +226,7 @@ class WebChatModel(ChatModel):
|
||||
max_new_tokens=max_new_tokens,
|
||||
top_p=top_p,
|
||||
temperature=temperature,
|
||||
seed=None if seed is None or int(seed) < 0 else int(seed),
|
||||
skip_special_tokens=skip_special_tokens,
|
||||
):
|
||||
response += new_text
|
||||
|
||||
@@ -85,6 +85,7 @@ def create_chat_box(
|
||||
max_new_tokens = gr.Slider(minimum=8, maximum=8192, value=1024, step=1)
|
||||
top_p = gr.Slider(minimum=0.01, maximum=1.0, value=0.7, step=0.01)
|
||||
temperature = gr.Slider(minimum=0.01, maximum=1.5, value=0.95, step=0.01)
|
||||
seed = gr.Number(value=-1, precision=0)
|
||||
skip_special_tokens = gr.Checkbox(value=True)
|
||||
escape_html = gr.Checkbox(value=True)
|
||||
enable_thinking = gr.Checkbox(value=True)
|
||||
@@ -110,6 +111,7 @@ def create_chat_box(
|
||||
max_new_tokens,
|
||||
top_p,
|
||||
temperature,
|
||||
seed,
|
||||
skip_special_tokens,
|
||||
escape_html,
|
||||
enable_thinking,
|
||||
@@ -135,6 +137,7 @@ def create_chat_box(
|
||||
max_new_tokens=max_new_tokens,
|
||||
top_p=top_p,
|
||||
temperature=temperature,
|
||||
seed=seed,
|
||||
skip_special_tokens=skip_special_tokens,
|
||||
escape_html=escape_html,
|
||||
enable_thinking=enable_thinking,
|
||||
|
||||
@@ -55,10 +55,13 @@ def create_eval_tab(engine: "Engine") -> dict[str, "Component"]:
|
||||
max_new_tokens = gr.Slider(minimum=8, maximum=4096, value=512, step=1)
|
||||
top_p = gr.Slider(minimum=0.01, maximum=1, value=0.7, step=0.01)
|
||||
temperature = gr.Slider(minimum=0.01, maximum=1.5, value=0.95, step=0.01)
|
||||
eval_seed = gr.Textbox(value="42")
|
||||
output_dir = gr.Textbox()
|
||||
|
||||
input_elems.update({max_new_tokens, top_p, temperature, output_dir})
|
||||
elem_dict.update(dict(max_new_tokens=max_new_tokens, top_p=top_p, temperature=temperature, output_dir=output_dir))
|
||||
input_elems.update({max_new_tokens, top_p, temperature, eval_seed, output_dir})
|
||||
elem_dict.update(
|
||||
dict(max_new_tokens=max_new_tokens, top_p=top_p, temperature=temperature, eval_seed=eval_seed, output_dir=output_dir)
|
||||
)
|
||||
|
||||
with gr.Row():
|
||||
cmd_preview_btn = gr.Button()
|
||||
|
||||
@@ -52,15 +52,17 @@ def create_train_tab(engine: "Engine") -> dict[str, "Component"]:
|
||||
learning_rate = gr.Textbox(value="5e-5")
|
||||
num_train_epochs = gr.Textbox(value="3.0")
|
||||
max_grad_norm = gr.Textbox(value="1.0")
|
||||
train_seed = gr.Textbox(value="42")
|
||||
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})
|
||||
input_elems.update({learning_rate, num_train_epochs, max_grad_norm, train_seed, max_samples, compute_type})
|
||||
elem_dict.update(
|
||||
dict(
|
||||
learning_rate=learning_rate,
|
||||
num_train_epochs=num_train_epochs,
|
||||
max_grad_norm=max_grad_norm,
|
||||
train_seed=train_seed,
|
||||
max_samples=max_samples,
|
||||
compute_type=compute_type,
|
||||
)
|
||||
|
||||
@@ -105,7 +105,7 @@ def check_template(lang: str, template: str) -> None:
|
||||
|
||||
|
||||
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.
|
||||
r"""Get training information for monitor.
|
||||
|
||||
If do_train is True:
|
||||
Inputs: top.lang, train.output_path
|
||||
|
||||
@@ -539,6 +539,28 @@ LOCALES = {
|
||||
"info": "勾配クリッピングのためのノルム。",
|
||||
},
|
||||
},
|
||||
"train_seed": {
|
||||
"en": {
|
||||
"label": "Seed",
|
||||
"info": "Random seed for training.",
|
||||
},
|
||||
"ru": {
|
||||
"label": "Seed",
|
||||
"info": "Random seed for training.",
|
||||
},
|
||||
"zh": {
|
||||
"label": "随机种子",
|
||||
"info": "训练使用的随机种子。",
|
||||
},
|
||||
"ko": {
|
||||
"label": "Seed",
|
||||
"info": "Random seed for training.",
|
||||
},
|
||||
"ja": {
|
||||
"label": "Seed",
|
||||
"info": "Random seed for training.",
|
||||
},
|
||||
},
|
||||
"max_samples": {
|
||||
"en": {
|
||||
"label": "Max samples",
|
||||
@@ -2708,6 +2730,45 @@ LOCALES = {
|
||||
"label": "温度",
|
||||
},
|
||||
},
|
||||
"seed": {
|
||||
"en": {
|
||||
"label": "Generation seed (-1 for random)",
|
||||
},
|
||||
"ru": {
|
||||
"label": "Generation seed (-1 = random)",
|
||||
},
|
||||
"zh": {
|
||||
"label": "生成随机种子(-1 表示随机)",
|
||||
},
|
||||
"ko": {
|
||||
"label": "Generation seed (-1 = random)",
|
||||
},
|
||||
"ja": {
|
||||
"label": "Generation seed (-1 = random)",
|
||||
},
|
||||
},
|
||||
"eval_seed": {
|
||||
"en": {
|
||||
"label": "Seed",
|
||||
"info": "Random seed for evaluation and prediction.",
|
||||
},
|
||||
"ru": {
|
||||
"label": "Seed",
|
||||
"info": "Random seed for evaluation and prediction.",
|
||||
},
|
||||
"zh": {
|
||||
"label": "随机种子",
|
||||
"info": "评估和预测使用的随机种子。",
|
||||
},
|
||||
"ko": {
|
||||
"label": "Seed",
|
||||
"info": "Random seed for evaluation and prediction.",
|
||||
},
|
||||
"ja": {
|
||||
"label": "Seed",
|
||||
"info": "Random seed for evaluation and prediction.",
|
||||
},
|
||||
},
|
||||
"skip_special_tokens": {
|
||||
"en": {
|
||||
"label": "Skip special tokens",
|
||||
|
||||
@@ -51,6 +51,13 @@ if TYPE_CHECKING:
|
||||
from .manager import Manager
|
||||
|
||||
|
||||
def _parse_seed(value: Any, default: int = 42) -> int:
|
||||
try:
|
||||
return int(value)
|
||||
except (TypeError, ValueError):
|
||||
return default
|
||||
|
||||
|
||||
class Runner:
|
||||
r"""A class to manage the running status of the trainers."""
|
||||
|
||||
@@ -147,6 +154,7 @@ class Runner:
|
||||
learning_rate=float(get("train.learning_rate")),
|
||||
num_train_epochs=float(get("train.num_train_epochs")),
|
||||
max_samples=int(get("train.max_samples")),
|
||||
seed=_parse_seed(get("train.train_seed")),
|
||||
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"),
|
||||
@@ -316,6 +324,7 @@ class Runner:
|
||||
max_new_tokens=get("eval.max_new_tokens"),
|
||||
top_p=get("eval.top_p"),
|
||||
temperature=get("eval.temperature"),
|
||||
seed=_parse_seed(get("eval.eval_seed")),
|
||||
output_dir=get_save_dir(model_name, finetuning_type, get("eval.output_dir")),
|
||||
trust_remote_code=True,
|
||||
ddp_timeout=180000000,
|
||||
|
||||
Reference in New Issue
Block a user