This commit is contained in:
Pascal 2025-12-17 05:51:07 +02:00 committed by GitHub
commit dbe630514e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 89 additions and 29 deletions

View File

@ -420,6 +420,8 @@ static bool common_params_parse_ex(int argc, char ** argv, common_params_context
} }
}; };
std::set<std::string> seen_args;
for (int i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
const std::string arg_prefix = "--"; const std::string arg_prefix = "--";
@ -430,6 +432,9 @@ static bool common_params_parse_ex(int argc, char ** argv, common_params_context
if (arg_to_options.find(arg) == arg_to_options.end()) { if (arg_to_options.find(arg) == arg_to_options.end()) {
throw std::invalid_argument(string_format("error: invalid argument: %s", arg.c_str())); throw std::invalid_argument(string_format("error: invalid argument: %s", arg.c_str()));
} }
if (!seen_args.insert(arg).second) {
LOG_WRN("DEPRECATED: argument '%s' specified multiple times, use comma-separated values instead (only last value will be used)\n", arg.c_str());
}
auto & tmp = arg_to_options[arg]; auto & tmp = arg_to_options[arg];
auto opt = *tmp.first; auto opt = *tmp.first;
bool is_positive = tmp.second; bool is_positive = tmp.second;
@ -750,6 +755,8 @@ bool common_params_to_map(int argc, char ** argv, llama_example ex, std::map<com
} }
}; };
std::set<std::string> seen_args;
for (int i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
const std::string arg_prefix = "--"; const std::string arg_prefix = "--";
@ -760,6 +767,9 @@ bool common_params_to_map(int argc, char ** argv, llama_example ex, std::map<com
if (arg_to_options.find(arg) == arg_to_options.end()) { if (arg_to_options.find(arg) == arg_to_options.end()) {
throw std::invalid_argument(string_format("error: invalid argument: %s", arg.c_str())); throw std::invalid_argument(string_format("error: invalid argument: %s", arg.c_str()));
} }
if (!seen_args.insert(arg).second) {
LOG_WRN("DEPRECATED: argument '%s' specified multiple times, use comma-separated values instead (only last value will be used)\n", arg.c_str());
}
auto opt = *arg_to_options[arg]; auto opt = *arg_to_options[arg];
std::string val; std::string val;
if (opt.value_hint != nullptr) { if (opt.value_hint != nullptr) {
@ -1226,13 +1236,15 @@ common_params_context common_params_parser_init(common_params & params, llama_ex
).set_examples({LLAMA_EXAMPLE_COMPLETION, LLAMA_EXAMPLE_CLI, LLAMA_EXAMPLE_DIFFUSION})); ).set_examples({LLAMA_EXAMPLE_COMPLETION, LLAMA_EXAMPLE_CLI, LLAMA_EXAMPLE_DIFFUSION}));
add_opt(common_arg( add_opt(common_arg(
{"--in-file"}, "FNAME", {"--in-file"}, "FNAME",
"an input file (repeat to specify multiple files)", "an input file (use comma-separated values to specify multiple files)",
[](common_params & params, const std::string & value) { [](common_params & params, const std::string & value) {
std::ifstream file(value); for (const auto & item : string_split<std::string>(value, ',')) {
if (!file) { std::ifstream file(item);
throw std::runtime_error(string_format("error: failed to open file '%s'\n", value.c_str())); if (!file) {
throw std::runtime_error(string_format("error: failed to open file '%s'\n", item.c_str()));
}
params.in_files.push_back(item);
} }
params.in_files.push_back(value);
} }
).set_examples({LLAMA_EXAMPLE_IMATRIX})); ).set_examples({LLAMA_EXAMPLE_IMATRIX}));
add_opt(common_arg( add_opt(common_arg(
@ -1969,9 +1981,11 @@ common_params_context common_params_parser_init(common_params & params, llama_ex
).set_examples(mmproj_examples).set_env("LLAMA_ARG_MMPROJ_OFFLOAD")); ).set_examples(mmproj_examples).set_env("LLAMA_ARG_MMPROJ_OFFLOAD"));
add_opt(common_arg( add_opt(common_arg(
{"--image", "--audio"}, "FILE", {"--image", "--audio"}, "FILE",
"path to an image or audio file. use with multimodal models, can be repeated if you have multiple files\n", "path to an image or audio file. use with multimodal models, use comma-separated values for multiple files\n",
[](common_params & params, const std::string & value) { [](common_params & params, const std::string & value) {
params.image.emplace_back(value); for (const auto & item : string_split<std::string>(value, ',')) {
params.image.emplace_back(item);
}
} }
).set_examples({LLAMA_EXAMPLE_MTMD, LLAMA_EXAMPLE_CLI})); ).set_examples({LLAMA_EXAMPLE_MTMD, LLAMA_EXAMPLE_CLI}));
add_opt(common_arg( add_opt(common_arg(
@ -2218,12 +2232,39 @@ common_params_context common_params_parser_init(common_params & params, llama_ex
} }
)); ));
add_opt(common_arg( add_opt(common_arg(
{"--override-kv"}, "KEY=TYPE:VALUE", {"--override-kv"}, "KEY=TYPE:VALUE,...",
"advanced option to override model metadata by key. may be specified multiple times.\n" "advanced option to override model metadata by key. to specify multiple overrides, either use comma-separated or repeat this argument.\n"
"types: int, float, bool, str. example: --override-kv tokenizer.ggml.add_bos_token=bool:false", "types: int, float, bool, str. example: --override-kv tokenizer.ggml.add_bos_token=bool:false,tokenizer.ggml.add_eos_token=bool:false",
[](common_params & params, const std::string & value) { [](common_params & params, const std::string & value) {
if (!string_parse_kv_override(value.c_str(), params.kv_overrides)) { std::vector<std::string> kv_overrides;
throw std::runtime_error(string_format("error: Invalid type for KV override: %s\n", value.c_str()));
std::string current;
bool escaping = false;
for (const char c : value) {
if (escaping) {
current.push_back(c);
escaping = false;
} else if (c == '\\') {
escaping = true;
} else if (c == ',') {
kv_overrides.push_back(current);
current.clear();
} else {
current.push_back(c);
}
}
if (escaping) {
current.push_back('\\');
}
kv_overrides.push_back(current);
for (const auto & kv_override : kv_overrides) {
if (!string_parse_kv_override(kv_override.c_str(), params.kv_overrides)) {
throw std::runtime_error(string_format("error: Invalid type for KV override: %s\n", kv_override.c_str()));
}
} }
} }
)); ));
@ -2237,33 +2278,50 @@ common_params_context common_params_parser_init(common_params & params, llama_ex
)); ));
add_opt(common_arg( add_opt(common_arg(
{"--lora"}, "FNAME", {"--lora"}, "FNAME",
"path to LoRA adapter (can be repeated to use multiple adapters)", "path to LoRA adapter (use comma-separated values to load multiple adapters)",
[](common_params & params, const std::string & value) { [](common_params & params, const std::string & value) {
params.lora_adapters.push_back({ std::string(value), 1.0, "", "", nullptr }); for (const auto & item : string_split<std::string>(value, ',')) {
params.lora_adapters.push_back({ item, 1.0, "", "", nullptr });
}
} }
// we define this arg on both COMMON and EXPORT_LORA, so when showing help message of export-lora, it will be categorized as "example-specific" arg // we define this arg on both COMMON and EXPORT_LORA, so when showing help message of export-lora, it will be categorized as "example-specific" arg
).set_examples({LLAMA_EXAMPLE_COMMON, LLAMA_EXAMPLE_EXPORT_LORA})); ).set_examples({LLAMA_EXAMPLE_COMMON, LLAMA_EXAMPLE_EXPORT_LORA}));
add_opt(common_arg( add_opt(common_arg(
{"--lora-scaled"}, "FNAME", "SCALE", {"--lora-scaled"}, "FNAME:SCALE,...",
"path to LoRA adapter with user defined scaling (can be repeated to use multiple adapters)", "path to LoRA adapter with user defined scaling (format: FNAME:SCALE,...)\n"
[](common_params & params, const std::string & fname, const std::string & scale) { "note: use comma-separated values",
params.lora_adapters.push_back({ fname, std::stof(scale), "", "", nullptr }); [](common_params & params, const std::string & value) {
for (const auto & item : string_split<std::string>(value, ',')) {
auto parts = string_split<std::string>(item, ':');
if (parts.size() != 2) {
throw std::invalid_argument("lora-scaled format: FNAME:SCALE");
}
params.lora_adapters.push_back({ parts[0], std::stof(parts[1]), "", "", nullptr });
}
} }
// we define this arg on both COMMON and EXPORT_LORA, so when showing help message of export-lora, it will be categorized as "example-specific" arg // we define this arg on both COMMON and EXPORT_LORA, so when showing help message of export-lora, it will be categorized as "example-specific" arg
).set_examples({LLAMA_EXAMPLE_COMMON, LLAMA_EXAMPLE_EXPORT_LORA})); ).set_examples({LLAMA_EXAMPLE_COMMON, LLAMA_EXAMPLE_EXPORT_LORA}));
add_opt(common_arg( add_opt(common_arg(
{"--control-vector"}, "FNAME", {"--control-vector"}, "FNAME",
"add a control vector\nnote: this argument can be repeated to add multiple control vectors", "add a control vector\nnote: use comma-separated values to add multiple control vectors",
[](common_params & params, const std::string & value) { [](common_params & params, const std::string & value) {
params.control_vectors.push_back({ 1.0f, value, }); for (const auto & item : string_split<std::string>(value, ',')) {
params.control_vectors.push_back({ 1.0f, item, });
}
} }
)); ));
add_opt(common_arg( add_opt(common_arg(
{"--control-vector-scaled"}, "FNAME", "SCALE", {"--control-vector-scaled"}, "FNAME:SCALE,...",
"add a control vector with user defined scaling SCALE\n" "add a control vector with user defined scaling SCALE\n"
"note: this argument can be repeated to add multiple scaled control vectors", "note: use comma-separated values (format: FNAME:SCALE,...)",
[](common_params & params, const std::string & fname, const std::string & scale) { [](common_params & params, const std::string & value) {
params.control_vectors.push_back({ std::stof(scale), fname }); for (const auto & item : string_split<std::string>(value, ',')) {
auto parts = string_split<std::string>(item, ':');
if (parts.size() != 2) {
throw std::invalid_argument("control-vector-scaled format: FNAME:SCALE");
}
params.control_vectors.push_back({ std::stof(parts[1]), parts[0] });
}
} }
)); ));
add_opt(common_arg( add_opt(common_arg(
@ -2353,13 +2411,15 @@ common_params_context common_params_parser_init(common_params & params, llama_ex
).set_env("HF_TOKEN")); ).set_env("HF_TOKEN"));
add_opt(common_arg( add_opt(common_arg(
{"--context-file"}, "FNAME", {"--context-file"}, "FNAME",
"file to load context from (repeat to specify multiple files)", "file to load context from (use comma-separated values to specify multiple files)",
[](common_params & params, const std::string & value) { [](common_params & params, const std::string & value) {
std::ifstream file(value, std::ios::binary); for (const auto & item : string_split<std::string>(value, ',')) {
if (!file) { std::ifstream file(item, std::ios::binary);
throw std::runtime_error(string_format("error: failed to open file '%s'\n", value.c_str())); if (!file) {
throw std::runtime_error(string_format("error: failed to open file '%s'\n", item.c_str()));
}
params.context_files.push_back(item);
} }
params.context_files.push_back(value);
} }
).set_examples({LLAMA_EXAMPLE_RETRIEVAL})); ).set_examples({LLAMA_EXAMPLE_RETRIEVAL}));
add_opt(common_arg( add_opt(common_arg(