From 4b6557e222339b1b674761d9beb0d64d45d60470 Mon Sep 17 00:00:00 2001 From: ModelHub XC Date: Mon, 15 Jun 2026 02:06:16 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=EF=BC=8C=E7=94=B1ModelHub=20XC=E7=A4=BE=E5=8C=BA=E6=8F=90?= =?UTF-8?q?=E4=BE=9B=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Model: omerkaragulmez/XbyK-0.1 Source: Original Platform --- .gitattributes | 37 ++++++++++ README.md | 137 ++++++++++++++++++++++++++++++++++++++ chat_template.jinja | 87 ++++++++++++++++++++++++ config.json | 30 +++++++++ generation_config.json | 6 ++ gguf/Modelfile | 11 +++ gguf/XbyK-0.1-Q4_K_M.gguf | 3 + model.safetensors | 3 + tokenizer.json | 3 + tokenizer_config.json | 16 +++++ training_info.json | 7 ++ 11 files changed, 340 insertions(+) create mode 100644 .gitattributes create mode 100644 README.md create mode 100644 chat_template.jinja create mode 100644 config.json create mode 100644 generation_config.json create mode 100644 gguf/Modelfile create mode 100644 gguf/XbyK-0.1-Q4_K_M.gguf create mode 100644 model.safetensors create mode 100644 tokenizer.json create mode 100644 tokenizer_config.json create mode 100644 training_info.json diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8763f92 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,37 @@ +*.7z filter=lfs diff=lfs merge=lfs -text +*.arrow filter=lfs diff=lfs merge=lfs -text +*.bin filter=lfs diff=lfs merge=lfs -text +*.bz2 filter=lfs diff=lfs merge=lfs -text +*.ckpt filter=lfs diff=lfs merge=lfs -text +*.ftz filter=lfs diff=lfs merge=lfs -text +*.gz filter=lfs diff=lfs merge=lfs -text +*.h5 filter=lfs diff=lfs merge=lfs -text +*.joblib filter=lfs diff=lfs merge=lfs -text +*.lfs.* filter=lfs diff=lfs merge=lfs -text +*.mlmodel filter=lfs diff=lfs merge=lfs -text +*.model filter=lfs diff=lfs merge=lfs -text +*.msgpack filter=lfs diff=lfs merge=lfs -text +*.npy filter=lfs diff=lfs merge=lfs -text +*.npz filter=lfs diff=lfs merge=lfs -text +*.onnx filter=lfs diff=lfs merge=lfs -text +*.ot filter=lfs diff=lfs merge=lfs -text +*.parquet filter=lfs diff=lfs merge=lfs -text +*.pb filter=lfs diff=lfs merge=lfs -text +*.pickle filter=lfs diff=lfs merge=lfs -text +*.pkl filter=lfs diff=lfs merge=lfs -text +*.pt filter=lfs diff=lfs merge=lfs -text +*.pth filter=lfs diff=lfs merge=lfs -text +*.rar filter=lfs diff=lfs merge=lfs -text +*.safetensors filter=lfs diff=lfs merge=lfs -text +saved_model/**/* filter=lfs diff=lfs merge=lfs -text +*.tar.* filter=lfs diff=lfs merge=lfs -text +*.tar filter=lfs diff=lfs merge=lfs -text +*.tflite filter=lfs diff=lfs merge=lfs -text +*.tgz filter=lfs diff=lfs merge=lfs -text +*.wasm filter=lfs diff=lfs merge=lfs -text +*.xz filter=lfs diff=lfs merge=lfs -text +*.zip filter=lfs diff=lfs merge=lfs -text +*.zst filter=lfs diff=lfs merge=lfs -text +*tfevents* filter=lfs diff=lfs merge=lfs -text +gguf/XbyK-0.1-Q4_K_M.gguf filter=lfs diff=lfs merge=lfs -text +tokenizer.json filter=lfs diff=lfs merge=lfs -text diff --git a/README.md b/README.md new file mode 100644 index 0000000..7081082 --- /dev/null +++ b/README.md @@ -0,0 +1,137 @@ +--- +license: apache-2.0 +base_model: mistralai/Mistral-Nemo-Instruct-2407 +tags: + - kentico + - xperience + - fine-tuned + - community + - multilingual +language: + - en + - tr +pipeline_tag: text-generation +--- + +# XbyK-0.1 + +**XbyK-0.1** is a fine-tuned version of [mistralai/Mistral-Nemo-Instruct-2407](https://huggingface.co/mistralai/Mistral-Nemo-Instruct-2407) specialized for **Xperience by Kentico** — a digital experience platform (DXP). + +> ⚠️ **This is not an official Kentico product.** XbyK-0.1 is a community-driven research project with no affiliation to Kentico a.s. It is not endorsed, sponsored, or maintained by Kentico. No commercial intent of any kind. + +--- + +## Who we are? + +**As Portalgrup AI team,** we develop, build and maintane AI solutions. +Portalgrup founded in 2007, PortalGrup entered the thriving internet ecosystem with a singular focus: creating and managing web portals. +But as time unfolded, our journey took an exhilarating turn. +We transformed into a versatile digital solutions provider, extending our reach across a diverse spectrum of services. + +Portalgrup website: [More detail](https://portalgrup.com) + +## Version: 0.1 — Why So Early? + +This model is at version **0.1** because its current evaluation results reflect meaningful room for improvement. + +Evaluated on 30 questions drawn from the official Kentico Xperience documentation, scored by **Qwen3:32b** as an independent judge (0–10 scale): + +| Metric | Result | +|--------|--------| +| Average score | **5.7 / 10** | +| Score ≥ 7 rate | **40%** (12 / 30) | +| Average response time | 1.4s | + +The 0.1 versioning is intentional and honest — the model is functional and useful for many queries, but there are known dataset quality issues that will be addressed in future iterations. + +--- + +## Known Issues & Planned Improvements + +The following problems were identified through systematic evaluation and are documented here for full transparency: + +### Format Issues + +- **Question echo as heading** — Most responses start with `## {question text}` or `### {question text}`. This is caused by training examples where assistant answers included the question as a heading. + *Fix: strip heading prefixes from all assistant turns in the training data.* + +- **One-sentence truncated answers** — Some responses end abruptly after a single sentence (e.g., *"Xperience gives you complete control over your content."*). + *Fix: enforce minimum response depth in training examples.* + +### Factual Errors + +| Topic | Error | +|-------|-------| +| Headless draft vs. published | Model incorrectly states that draft items are accessible via the headless API — only **Published** items are | +| Content sync — image variants | Model gave an irrelevant e-commerce paragraph instead of answering the actual question | +| Automation license tier | Incomplete or incorrect license tier information | +| Email channel license tier | Wrong license threshold stated | + +### Terminology Inconsistencies + +- Model uses "Asset tiles" instead of the correct term **"content item assets"** +- Inconsistent usage of "Content Hub" vs. older naming conventions from previous Kentico versions + +### Weak Topic Coverage + +The following topics scored lowest and need additional training examples: + +| Topic | Issue | +|-------|-------| +| Pages vs. Content items | Core conceptual difference covered too superficially in training data | +| Content sync — image variants | Too few specific examples in the dataset | +| Headless draft / publish lifecycle | Frequently misunderstood; needs correct, emphatic examples | +| License tier comparisons (Automation, Email) | License feature tables not well-represented in training data | +| Smart Folder creation (step-by-step) | Procedural steps are missing from examples | + +--- + +## Capabilities + +- **Chat**: Answer questions about Kentico Xperience development, content management, digital marketing, e-commerce, and best practices +- **Multilingual**: English (primary) + inherited multilingual capabilities from Mistral-Nemo base + +## Training Data + +Fine-tuned on the official Kentico Xperience documentation: +- [docs.kentico.com](https://docs.kentico.com/) — Documentation, guides, and training materials +- [api-reference.kentico.com](https://api-reference.kentico.com/) — API reference + +The full training dataset is available at [omerkaragulmez/XbyK-0.1-dataset](https://huggingface.co/datasets/omerkaragulmez/XbyK-0.1-dataset). + +## Usage + +```python +from transformers import pipeline + +pipe = pipeline("text-generation", model="omerkaragulmez/XbyK-0.1", torch_dtype="bfloat16", device_map="auto") + +messages = [ + {"role": "user", "content": "How do I create a content type in Kentico Xperience?"} +] + +response = pipe(messages, max_new_tokens=512, temperature=0.3) +print(response[0]["generated_text"][-1]["content"]) +``` + +### With Ollama (recommended) + +The quantized GGUF (`gguf/XbyK-0.1-Q4_K_M.gguf`) is available in this repo and can be used directly with Ollama: + +```bash +ollama create xbyk-0.1 -f gguf/Modelfile +ollama run xbyk-0.1 "How do I use the Delivery API?" +``` + +## Training Details + +- **Base model**: mistralai/Mistral-Nemo-Instruct-2407 (12B parameters) +- **Method**: LoRA (Low-Rank Adaptation) +- **Hardware**: 2× NVIDIA GH200 +- **Framework**: HuggingFace TRL + PEFT + +--- + +## Disclaimer + +Xperience by Kentico™ is a registered trademark of Kentico a.s. This project is an independent community research effort and has no commercial intent. All documentation used for training is publicly available at docs.kentico.com diff --git a/chat_template.jinja b/chat_template.jinja new file mode 100644 index 0000000..9c21a3f --- /dev/null +++ b/chat_template.jinja @@ -0,0 +1,87 @@ +{%- if messages[0]["role"] == "system" %} + {%- set system_message = messages[0]["content"] %} + {%- set loop_messages = messages[1:] %} +{%- else %} + {%- set loop_messages = messages %} +{%- endif %} +{%- if not tools is defined %} + {%- set tools = none %} +{%- endif %} +{%- set user_messages = loop_messages | selectattr("role", "equalto", "user") | list %} + +{#- This block checks for alternating user/assistant messages, skipping tool calling messages #} +{%- set ns = namespace() %} +{%- set ns.index = 0 %} +{%- for message in loop_messages %} + {%- if not (message.role == "tool" or message.role == "tool_results" or (message.tool_calls is defined and message.tool_calls is not none)) %} + {%- if (message["role"] == "user") != (ns.index % 2 == 0) %} + {{- raise_exception("After the optional system message, conversation roles must alternate user/assistant/user/assistant/...") }} + {%- endif %} + {%- set ns.index = ns.index + 1 %} + {%- endif %} +{%- endfor %} + +{{- bos_token }} +{%- for message in loop_messages %} + {%- if message["role"] == "user" %} + {%- if tools is not none and (message == user_messages[-1]) %} + {{- "[AVAILABLE_TOOLS][" }} + {%- for tool in tools %} + {%- set tool = tool.function %} + {{- '{"type": "function", "function": {' }} + {%- for key, val in tool.items() if key != "return" %} + {%- if val is string %} + {{- '"' + key + '": "' + val + '"' }} + {%- else %} + {{- '"' + key + '": ' + val|tojson }} + {%- endif %} + {%- if not loop.last %} + {{- ", " }} + {%- endif %} + {%- endfor %} + {{- "}}" }} + {%- if not loop.last %} + {{- ", " }} + {%- else %} + {{- "]" }} + {%- endif %} + {%- endfor %} + {{- "[/AVAILABLE_TOOLS]" }} + {%- endif %} + {%- if loop.last and system_message is defined %} + {{- "[INST]" + system_message + "\n\n" + message["content"] + "[/INST]" }} + {%- else %} + {{- "[INST]" + message["content"] + "[/INST]" }} + {%- endif %} + {%- elif (message.tool_calls is defined and message.tool_calls is not none) %} + {{- "[TOOL_CALLS][" }} + {%- for tool_call in message.tool_calls %} + {%- set out = tool_call.function|tojson %} + {{- out[:-1] }} + {%- if not tool_call.id is defined or tool_call.id|length != 9 %} + {{- raise_exception("Tool call IDs should be alphanumeric strings with length 9!") }} + {%- endif %} + {{- ', "id": "' + tool_call.id + '"}' }} + {%- if not loop.last %} + {{- ", " }} + {%- else %} + {{- "]" + eos_token }} + {%- endif %} + {%- endfor %} + {%- elif message["role"] == "assistant" %} + {{- message["content"] + eos_token}} + {%- elif message["role"] == "tool_results" or message["role"] == "tool" %} + {%- if message.content is defined and message.content.content is defined %} + {%- set content = message.content.content %} + {%- else %} + {%- set content = message.content %} + {%- endif %} + {{- '[TOOL_RESULTS]{"content": ' + content|string + ", " }} + {%- if not message.tool_call_id is defined or message.tool_call_id|length != 9 %} + {{- raise_exception("Tool call IDs should be alphanumeric strings with length 9!") }} + {%- endif %} + {{- '"call_id": "' + message.tool_call_id + '"}[/TOOL_RESULTS]' }} + {%- else %} + {{- raise_exception("Only user and assistant roles are supported, with the exception of an initial optional system message!") }} + {%- endif %} +{%- endfor %} diff --git a/config.json b/config.json new file mode 100644 index 0000000..56ca390 --- /dev/null +++ b/config.json @@ -0,0 +1,30 @@ +{ + "architectures": [ + "MistralForCausalLM" + ], + "attention_dropout": 0.0, + "bos_token_id": 1, + "dtype": "bfloat16", + "eos_token_id": 2, + "head_dim": 128, + "hidden_act": "silu", + "hidden_size": 5120, + "initializer_range": 0.02, + "intermediate_size": 14336, + "max_position_embeddings": 131072, + "model_type": "mistral", + "num_attention_heads": 32, + "num_hidden_layers": 40, + "num_key_value_heads": 8, + "pad_token_id": null, + "rms_norm_eps": 1e-05, + "rope_parameters": { + "rope_theta": 1000000.0, + "rope_type": "default" + }, + "sliding_window": null, + "tie_word_embeddings": false, + "transformers_version": "5.4.0", + "use_cache": true, + "vocab_size": 131072 +} diff --git a/generation_config.json b/generation_config.json new file mode 100644 index 0000000..8b87e85 --- /dev/null +++ b/generation_config.json @@ -0,0 +1,6 @@ +{ + "_from_model_config": true, + "bos_token_id": 1, + "eos_token_id": 2, + "transformers_version": "5.4.0" +} diff --git a/gguf/Modelfile b/gguf/Modelfile new file mode 100644 index 0000000..27737be --- /dev/null +++ b/gguf/Modelfile @@ -0,0 +1,11 @@ +FROM ./XbyK-0.1-Q4_K_M.gguf + +PARAMETER temperature 0.3 +PARAMETER top_p 0.9 +PARAMETER num_ctx 4096 + +SYSTEM """You are XbyK-0.1, an expert AI assistant for Xperience by Kentico. +You help developers, marketers, and administrators with questions about +Kentico Xperience — including development, content management, deployment, +API usage, and best practices. You provide accurate, detailed answers +based on the official Kentico documentation.""" diff --git a/gguf/XbyK-0.1-Q4_K_M.gguf b/gguf/XbyK-0.1-Q4_K_M.gguf new file mode 100644 index 0000000..4f451dc --- /dev/null +++ b/gguf/XbyK-0.1-Q4_K_M.gguf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:66e8adf9ac8d022d241729af84f2639d9c8a2d4a9f1351b550d6d5f3297b923d +size 7477207968 diff --git a/model.safetensors b/model.safetensors new file mode 100644 index 0000000..257ebf4 --- /dev/null +++ b/model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ad9e4165bf011198e733a62bb70f70cf31f42681352792ed2aee4c00edb2c28b +size 24495607560 diff --git a/tokenizer.json b/tokenizer.json new file mode 100644 index 0000000..4e74d59 --- /dev/null +++ b/tokenizer.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b0240ce510f08e6c2041724e9043e33be9d251d1e4a4d94eb68cd47b954b61d2 +size 17078292 diff --git a/tokenizer_config.json b/tokenizer_config.json new file mode 100644 index 0000000..bf4f5d7 --- /dev/null +++ b/tokenizer_config.json @@ -0,0 +1,16 @@ +{ + "add_prefix_space": false, + "backend": "tokenizers", + "bos_token": "", + "clean_up_tokenization_spaces": false, + "eos_token": "", + "is_local": false, + "model_input_names": [ + "input_ids", + "attention_mask" + ], + "model_max_length": 1000000000000000019884624838656, + "pad_token": "", + "tokenizer_class": "TokenizersBackend", + "unk_token": "" +} diff --git a/training_info.json b/training_info.json new file mode 100644 index 0000000..1c488fd --- /dev/null +++ b/training_info.json @@ -0,0 +1,7 @@ +{ + "model_name": "XbyK-0.1", + "base_model": "mistralai/Mistral-Nemo-Instruct-2407", + "merge_dtype": "bfloat16", + "lora_rank": 32, + "lora_alpha": 64 +} \ No newline at end of file