Downloads · 30 days
19
13% of all-time downloads
asphyxiation112/gemma4-it-kaltsit-lora
gemma4-it-kaltsit-lora is a text generation model from asphyxiation112. Use it when you need the model to write or continue text. It is set up for peft. The card lists the license as other.
This project fine-tunes google/gemma-4-E4B-it with LoRA to generate Chinese dialogue in the style of Kal'tsit from Arknights. The goal is not to train a full model from scratch, but to adapt a large instruction-tuned…
Downloads · 30 days
19
13% of all-time downloads
All-time downloads
143
Public
Repo size
547 MB
Likes
0
Public
Click a slice to open those files.
.pt312 MB · 44%
From the Hugging Face model README
This project fine-tunes google/gemma-4-E4B-it with LoRA to generate Chinese dialogue in the style of Kal'tsit from Arknights. The goal is not to train a full model from scratch, but to adapt a large instruction-tuned base model with a lightweight PEFT adapter so that it better follows a specific character voice: calm, restrained, analytical, and context-aware.
The project covers the full workflow from story data collection, text cleaning, character-specific dataset construction, prompt design, SFT formatting, LoRA training, validation monitoring, test generation, and optional adapter merging. The main training workflow is documented in gemma4_emotion_lora_arknights.ipynb.
The raw data was collected from Arknights story pages through ASTR story reader URLs. The URL list is stored in urls.txt and contains 263 story links. The data collection script is scripts/download_arknights_story.py.
The collection pipeline works as follows:
ArknightsStoryJson repository, using the pattern zh_CN/gamedata/story/{story_path}.json.requests.storyList and extract attributes.name as the speaker and attributes.content as the dialogue text.Sticker text as on-screen text..txt and structured .jsonl files.Each structured line uses the following format:
{"speaker": "凯尔希", "text": "dialogue text"}
The character dataset is then built with scripts/build_character_dataset.py:
.jsonl files from the result folder in sorted order.凯尔希.Final dataset size:
| Split | Samples |
|---|---|
| Train | 2680 |
| Validation | 335 |
| Test | 335 |
| Total | 3350 |
Each training sample is converted into a chat-style prompt and assistant completion. The notebook uses the official tokenizer chat template to format the data for Gemma.
System prompt:
你正在扮演《明日方舟》中的凯尔希。
请根据用户给出的上下文进行回复。
要求:
1. 只输出凯尔希的回复内容。
2. 不要解释你为什么这样回复。
3. 不要输出“凯尔希:”这个角色名前缀。
4. 语气应冷静、克制、理性,句子可以偏长。
5. 回复应尽量贴合上下文,而不是机械复述已有台词。
User prompt template:
请根据上下文,以凯尔希的说话风格进行回复。
上下文:
[Character A]:previous line
[Character B]:previous line
[凯尔希]:previous line
The assistant completion is the target Kal'tsit response. In other words, the model is trained to generate the next character-style reply from context, rather than to classify text into labels.
The base model is google/gemma-4-E4B-it, downloaded from ModelScope and loaded from a local directory. Training uses single-GPU BF16 LoRA fine-tuning with PEFT and TRL SFTTrainer. The notebook loads the model with AutoModelForCausalLM and saves the final adapter and tokenizer.
Core training configuration:
| Item | Value |
|---|---|
| Base model | google/gemma-4-E4B-it |
| Fine-tuning method | LoRA / PEFT |
| Trainer | TRL SFTTrainer |
| LoRA rank | 8 |
| LoRA alpha | 16 |
| LoRA dropout | 0.05 |
| Target modules | all-linear |
| Trainable parameters | 25,249,792 |
| Total parameters during PEFT training | 7,966,350,624 |
| Trainable ratio | 0.3170% |
| Epochs | 2 |
| Global steps | 336 |
| Per-device batch size | 2 |
| Gradient accumulation | 8 |
| Learning rate | 5e-5 |
| Scheduler | cosine |
| Warmup steps | 10 |
| Max sequence length | 512 |
| Loss mode | completion-only loss |
| Precision | BF16 |
| Evaluation interval | every 50 steps |
| Checkpoint selection | best eval_loss |
Training workflow:
DatasetDict.SFTTrainer.Training completed successfully at global_step=336, and the best checkpoint was checkpoint-336, which is also the final step. Total training time was about 1993 seconds, or 33.2 minutes.
Validation metrics:
| Step | Eval loss | Eval token accuracy |
|---|---|---|
| 50 | 3.1132 | 0.4541 |
| 100 | 2.9867 | 0.4716 |
| 150 | 2.9440 | 0.4739 |
| 200 | 2.9127 | 0.4758 |
| 250 | 2.8917 | 0.4769 |
| 300 | 2.8853 | 0.4801 |
| 336 | 2.8843 | 0.4788 |
The final test generation file is kaltsit_test_generations.csv, with 335 generated responses. There were no empty outputs and no generated responses with the unwanted 凯尔希: role prefix. The average target response length was 23.42 Chinese characters, while the average generated response length was 16.53 characters.
Qualitatively, the model learned part of the target style, especially restrained phrasing, concise responses, and role-prefix control. However, the test set also shows limitations. The response ...... appears 38 times, and 20 generated responses are 4 characters or shorter. This suggests that the LoRA adapter is valid and learned useful stylistic behavior, but it is not yet a high-quality story continuation model.
My interpretation of the result:
Main artifacts:
| File | Description |
|---|---|
adapter_model.safetensors | LoRA adapter weights |
adapter_config.json | PEFT/LoRA configuration |
tokenizer.json / tokenizer_config.json | Tokenizer files |
chat_template.jinja | Gemma 4 chat template |
train_metrics.json | Training summary metrics |
kaltsit_test_generations.csv | Test-set generations |
checkpoint-300 / checkpoint-336 | Training checkpoints |
This repository currently contains the LoRA adapter, not a fully merged model. To deploy a merged model, the matching google/gemma-4-E4B-it base model must be loaded, the adapter must be attached with PeftModel.from_pretrained, and the weights can then be merged with merge_and_unload(). The full processor should also be saved with the merged model.
Data pipeline files:
| File | Description |
|---|---|
scripts/download_arknights_story.py | Downloads and parses raw Arknights story JSON files from ASTR URLs |
scripts/build_character_dataset.py | Builds the Kal'tsit SFT dataset and creates train/validation/test splits |
scripts/count_speakers.py | Counts speaker frequencies in the parsed story JSONL files |
requirements.txt | Minimal dependency list for the data collection scripts |
urls.txt | Source ASTR story URL list used for data collection |
Minimal data pipeline reproduction:
pip install -r requirements.txt
python scripts/download_arknights_story.py --url-file urls.txt --jsonl
python scripts/build_character_dataset.py --input-dir result --character 凯尔希 --output-dir dataset --context-size 3
python scripts/count_speakers.py
...... and ——.This section records the post-training workflow completed after the LoRA adapter was trained: merging the adapter into the base model, fixing deployment-specific compatibility issues, serving the merged model with vLLM, and evaluating the final inference behavior.
The LoRA adapter was merged into the local google/gemma-4-E4B-it base model and saved as a standalone Hugging Face-format model:
/root/models_cache/google/gemma-4-E4B-it-kaltsit-merged
The merge used AutoTokenizer + AutoModelForImageTextToText + PeftModel.merge_and_unload(). AutoProcessor was avoided during the merge because the ROCm environment triggered a torchvision import chain that was not fully compatible with the installed PyTorch build. For this text-only LoRA experiment, the tokenizer and model were sufficient for merging.
The merged model was served with vLLM as an OpenAI-compatible API:
vllm serve /root/models_cache/google/gemma-4-E4B-it-kaltsit-merged \
--host 0.0.0.0 \
--port 8000 \
--served-model-name gemma4-kaltsit \
--dtype bfloat16 \
--trust-remote-code \
--max-model-len 4096 \
--gpu-memory-utilization 0.90 \
--generation-config vllm
The deployment used vLLM 0.24.0+rocm723. Both /v1/models and /v1/chat/completions returned HTTP 200, confirming that the merged model could be called through the OpenAI-compatible API.
torchvision / processor import failureIn the ROCm runtime, the transformers processor import path triggered torchvision, while the installed torchvision/torchaudio versions were not fully compatible with torch 2.11.0+gitd0c8b1f. This caused import failures during the merge/deployment stage.
Fixes:
AutoProcessor and used AutoTokenizer + AutoModelForImageTextToText.torchvision==0.27.1 was installed for the vLLM serving path.torchvision::nms fake registration was temporarily skipped. This is an environment-specific workaround; a clean reproduction should use a fully matched ROCm/PyTorch/torchvision image.k_norm.weight keys for vLLMvLLM's Gemma4 loader expected self_attn.k_norm.weight for some shared-KV layers, but the merged safetensors checkpoint did not contain those keys.
Fix:
k_norm.weight keys were found.q_norm.weight was copied into the missing k_norm.weight.model-vllm-extra-k-norm.safetensors.model.safetensors.index.json was updated, with a backup kept before the patch.This was a vLLM compatibility patch, not additional model training.
A multi-line curl command was initially written inside a Python notebook cell with ! only on the first line. The JSON body was then parsed as Python code, causing an IndentationError.
Fix:
%%bash for multi-line shell commands.urllib.request to call the OpenAI-compatible API.The ROCm/aiter runtime printed a warning that NUMA balancing was enabled. It did not stop this experiment, but ROCm recommends disabling NUMA auto balancing on relevant AMD systems if runtime instability appears.
The following screenshot shows the final vLLM inference session using a prompt closer to the training format.

The initial smoke test only produced:
......
Later open-ended prompts produced longer responses, but revealed clear limitations:
The final tests used a prompt closer to the training distribution:
请根据上下文,以凯尔希的说话风格进行回复。
Under this format, the model improved:
| Input | Output summary | Observation |
|---|---|---|
这片大地,还有感染者的位置吗。 | (微微颔首)是的。 | Concise and restrained, but too short |
这片大地,感染者应该如何生存下去。 | A longer response about survival, hope, and responsibility | Closer to the desired character atmosphere |
泰拉大陆最终会变成什么样子。 | 我不知道。... 我们所做的一切,我们的努力,终将不被辜负。 | Better tone, but still has pronoun and narrative stability issues |
Overall, the model can be deployed with vLLM and can generate Kal'tsit-like restrained, heavy, and analytical text when prompted in the training style. However, it is not yet a reliable character model. Open-ended Q&A, lore consistency, factual grounding, and long-context continuity still need more work.