81 auto it =
gguf.metadata.find(key);
82 if (
it !=
gguf.metadata.end() &&
83 std::holds_alternative<std::string>(
it->second)) {
84 return std::get<std::string>(
it->second);
91 auto it =
gguf.metadata.find(key);
92 if (
it !=
gguf.metadata.end()) {
95 using T = std::decay_t<
decltype(
val)>;
97 if constexpr (std::is_integral_v<TargetType>) {
98 if constexpr (std::is_integral_v<T> && !std::is_same_v<T, bool>) {
99 if constexpr (std::is_unsigned_v<T> &&
100 std::is_signed_v<TargetType>) {
101 if (
val >
static_cast<std::make_unsigned_t<TargetType>
>(
102 std::numeric_limits<TargetType>::max())) {
104 std::to_string(
val) +
105 " overflows TargetType. Using default.");
110 else if constexpr (std::is_signed_v<T> &&
111 std::is_signed_v<TargetType> &&
113 if (
val >
static_cast<T>(
114 std::numeric_limits<TargetType>::max()) ||
115 val <
static_cast<T>(
116 std::numeric_limits<TargetType>::lowest())) {
118 std::to_string(
val) +
119 " overflows TargetType. Using default.");
125 }
else if constexpr (std::is_floating_point_v<TargetType>) {
126 if constexpr (std::is_floating_point_v<T>) {
129 }
else if constexpr (std::is_same_v<TargetType, bool>) {
130 if constexpr (std::is_same_v<T, bool>) {
133 }
else if constexpr (std::is_same_v<TargetType, std::string>) {
134 if constexpr (std::is_same_v<T, std::string>) {
139 "' has stored type incompatible with requested "
140 "TargetType. Using default.");
169 config.num_attention_heads)));
173 if (
config.max_position_embeddings == 0 ||
174 config.max_position_embeddings > 8192) {
176 std::to_string(
config.max_position_embeddings) +
177 ", overriding to sensible default (2048)");
178 config.max_position_embeddings = 2048;
183 get_meta_value(
"mistral.attention.layer_norm_rms_epsilon", 1e-5f)));
193 if (
config.hidden_act.empty()) {
195 if (arch.find(
"phi") != std::string::npos || arch.find(
"Phi") != std::string::npos) {
196 config.hidden_act =
"gelu_new";
197 Logger::info(
"[parse_gguf_config] Phi architecture detected, defaulting hidden_act to 'gelu_new'");
199 config.hidden_act =
"silu";
214 ", Vocab Size: " + std::to_string(
config.vocab_size) +
215 ", Has Merges: " + (
has_merges ?
"Yes" :
"No"));
218 Logger::info(
"[parse_gguf_config] Identifying tokenizer family...");
220 config.architecture.find(
"Llama-3") != std::string::npos ||
221 config.architecture.find(
"Meta-Llama-3") != std::string::npos);
228 ", has_merges=" + std::string(
has_merges ?
"Y":
"N") +
236 Logger::info(
"[parse_gguf_config] Result: Identified WORD_LEVEL tokenizer "
237 "(tokenizer.ggml.model='word'; transformer_cpp export).");
240 Logger::info(
"[parse_gguf_config] Result: Identified LLAMA3_TIKTOKEN (merges + vocab_size + ggml_tokenizer_model='gpt2'). Architecture string was: '" +
config.architecture +
"'");
242 Logger::info(
"[parse_gguf_config] Note: Classified as Llama 3 based on tokenizer/vocab, but arch string was 'llama'.");
244 if (
config.rope_theta == 10000.0f) {
248 Logger::info(
"[parse_gguf_config] Adjusted rope_theta to " + std::to_string(
config.rope_theta) +
" for Llama 3 model (was 10000.0).");
251 }
else if (
config.architecture ==
"llama" ||
config.architecture.find(
"Llama-2") != std::string::npos ||
config.architecture.find(
"TinyLlama") != std::string::npos) {
253 Logger::info(
"[parse_gguf_config] Result: Identified LLAMA_SENTENCEPIECE based on architecture: '" +
config.architecture +
"'");
256 Logger::info(
"[parse_gguf_config] Result: UNKNOWN tokenizer family for architecture: '" +
config.architecture +
"'");
260 if (
config.model_name.find(
"TinyLlama") != std::string::npos ||
262 config.chat_template_type =
"tinyllama";
264 config.chat_template_type =
"llama2";
266 config.chat_template_type =
"unknown";
273 config.pre_tokenizer_type =
275 }
else if (
config.architecture ==
"llama") {
276 config.pre_tokenizer_type =
"llama";
278 config.pre_tokenizer_type =
"unknown";
281 "', model_name='" +
config.model_name +
"', chat_template='" +
282 config.chat_template_type +
"', pre_tokenizer='" +
283 config.pre_tokenizer_type +
"'");
285 if (
config.model_name ==
"llama" &&
config.pre_tokenizer_type !=
"llama") {
286 config.chat_template_type =
"llama2";
288 "Inferred chat_template_type='llama2' based on model_type and "
289 "missing/different pre_tokenizer_type.");
294 std::holds_alternative<std::string>(
template_it->second)) {
296 Logger::info(
"Found tokenizer.chat_template in metadata.");
300 "tokenizer.chat_template not found or not a string in metadata. Will "
301 "use fallback logic.");
302 config.chat_template_string =
"";
304 if (
config.chat_template_type ==
"unknown") {
305 if (
config.model_name ==
"llama" &&
config.pre_tokenizer_type !=
"llama") {
306 config.chat_template_type =
"llama2";
308 "Inferred chat_template_type='llama2' based on model name and "
309 "missing/different pre_tokenizer_type.");
311 Logger::info(
"Llama 3 model identified. Chat template will primarily rely on 'tokenizer.chat_template' from GGUF if present.");
313 if (
gguf.metadata.count(
"tokenizer.chat_template")) {
314 config.chat_template_type =
"llama3_gguf_direct";
316 config.chat_template_type =
"llama3_fallback";
317 Logger::warning(
"Llama 3 model detected, but 'tokenizer.chat_template' not found in GGUF metadata.");
322 Logger::info(std::string(
"[parse_gguf_config] Finished parsing. Returning config. Family: ") +