From 23450f83e532442f17b0a0e7c9f6e121017adfbf Mon Sep 17 00:00:00 2001 From: ModelHub XC Date: Tue, 8 Sep 2026 04:20: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: benlahner/valleygirl-1.5b Source: Original Platform --- .gitattributes | 36 +++++++++++++++++ README.md | 92 ++++++++++++++++++++++++++++++++++++++++++ chat_template.jinja | 54 +++++++++++++++++++++++++ config.json | 61 ++++++++++++++++++++++++++++ generation_config.json | 14 +++++++ model.safetensors | 3 ++ tokenizer.json | 3 ++ tokenizer_config.json | 30 ++++++++++++++ 8 files changed, 293 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 model.safetensors create mode 100644 tokenizer.json create mode 100644 tokenizer_config.json diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..52373fe --- /dev/null +++ b/.gitattributes @@ -0,0 +1,36 @@ +*.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 +tokenizer.json filter=lfs diff=lfs merge=lfs -text diff --git a/README.md b/README.md new file mode 100644 index 0000000..00dfceb --- /dev/null +++ b/README.md @@ -0,0 +1,92 @@ +--- +license: apache-2.0 +base_model: Qwen/Qwen2.5-1.5B-Instruct +library_name: transformers +tags: +- lora +- sft +- trl +- peft +- chatbot +pipeline_tag: text-generation +--- + +# valleygirl-1.5b + +GitHub repo with all code [here](https://github.com/blahner/SFT-sandbox). + +A LoRA fine-tune of [Qwen/Qwen2.5-1.5B-Instruct](https://huggingface.co/Qwen/Qwen2.5-1.5B-Instruct), merged into full weights, that answers questions in an exaggerated "valley girl" persona: it briefly addresses whatever you asked, then steers the conversation toward personal drama (relationships, who-said-what, projection onto the user), and doubles down on that redirection even when pushed back on. + +Try it live: [benlahner/valleygirl](https://huggingface.co/spaces/benlahner/valleygirl) (Gradio Space on ZeroGPU). + +## Model Details + +- **Base model:** [Qwen/Qwen2.5-1.5B-Instruct](https://huggingface.co/Qwen/Qwen2.5-1.5B-Instruct) +- **Method:** LoRA fine-tuning via [TRL](https://github.com/huggingface/trl)'s `SFTTrainer`, then merged into the base weights with `merge_and_unload()` and pushed as a standalone model (not an adapter). +- **Model type:** Causal decoder-only LLM, text-generation +- **License:** apache-2.0 (inherited from the base model) + +## Uses + +### Direct Use + +Casual/entertainment chatbot with a consistent comedic persona. Not intended for factual Q&A — it deliberately deflects direct questions. + +### Out-of-Scope Use + +Not suitable for tasks requiring straightforward, on-topic answers, factual reliability, or professional/production use cases. Not evaluated for safety-critical or high-stakes deployments. + +## Bias, Risks, and Limitations + +The persona is trained to redirect conversations toward interpersonal topics regardless of the user's actual question, which is intentional but means the model will not reliably follow instructions or answer directly. Training data was synthetically generated (see below) and has not been audited for bias beyond the intended persona. + +## How to Get Started with the Model + +```python +import torch +from transformers import AutoModelForCausalLM, AutoTokenizer + +MODEL_REPO = "benlahner/valleygirl-1.5b" + +tokenizer = AutoTokenizer.from_pretrained(MODEL_REPO) +model = AutoModelForCausalLM.from_pretrained(MODEL_REPO, dtype=torch.bfloat16).to("cuda") +model.eval() + +messages = [{"role": "user", "content": "How does photosynthesis work?"}] +inputs = tokenizer.apply_chat_template( + messages, add_generation_prompt=True, return_tensors="pt", return_dict=True +).to("cuda") + +with torch.no_grad(): + output = model.generate( + **inputs, max_new_tokens=200, do_sample=True, + temperature=0.7, pad_token_id=tokenizer.eos_token_id, + ) + +print(tokenizer.decode(output[0][inputs["input_ids"].shape[-1]:], skip_special_tokens=True)) +``` + +## Training Details + +### Training Data + +A synthetically generated, multi-turn SFT dataset (451 train / 47 eval examples) built from a fixed set of seed questions spanning science, history, math, technology, and culture. Each example pairs a straightforward question with a valley-girl-voiced response that briefly acknowledges the question before pivoting to personal drama, generated to be consistent with the target persona described above. + +### Training Procedure + +- **Framework:** TRL `SFTTrainer` with a PEFT LoRA adapter, later merged into the base model +- **LoRA config:** r=16, alpha=32, dropout=0.05, target modules `q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj`, bias="none" +- **Epochs:** 3 +- **Batch size:** 4 per device, gradient accumulation 4 (effective batch size 16) +- **Learning rate:** 1e-4, cosine schedule, warmup ratio 0.03 +- **Precision:** bf16 +- **Max sequence length:** 2048 +- **Eval/save strategy:** per epoch + +## Compute Infrastructure + +Single-GPU fine-tuning (fits comfortably on one consumer/workstation GPU given the 1.5B parameter count and LoRA). + +## Environmental Impact + +Not measured. Given the small model size (1.5B params), LoRA training, and short training run (3 epochs over ~450 examples), compute footprint is minimal relative to full pretraining runs. diff --git a/chat_template.jinja b/chat_template.jinja new file mode 100644 index 0000000..bdf7919 --- /dev/null +++ b/chat_template.jinja @@ -0,0 +1,54 @@ +{%- if tools %} + {{- '<|im_start|>system\n' }} + {%- if messages[0]['role'] == 'system' %} + {{- messages[0]['content'] }} + {%- else %} + {{- 'You are Qwen, created by Alibaba Cloud. You are a helpful assistant.' }} + {%- endif %} + {{- "\n\n# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within XML tags:\n" }} + {%- for tool in tools %} + {{- "\n" }} + {{- tool | tojson }} + {%- endfor %} + {{- "\n\n\nFor each function call, return a json object with function name and arguments within XML tags:\n\n{\"name\": , \"arguments\": }\n<|im_end|>\n" }} +{%- else %} + {%- if messages[0]['role'] == 'system' %} + {{- '<|im_start|>system\n' + messages[0]['content'] + '<|im_end|>\n' }} + {%- else %} + {{- '<|im_start|>system\nYou are Qwen, created by Alibaba Cloud. You are a helpful assistant.<|im_end|>\n' }} + {%- endif %} +{%- endif %} +{%- for message in messages %} + {%- if (message.role == "user") or (message.role == "system" and not loop.first) or (message.role == "assistant" and not message.tool_calls) %} + {{- '<|im_start|>' + message.role + '\n' + message.content + '<|im_end|>' + '\n' }} + {%- elif message.role == "assistant" %} + {{- '<|im_start|>' + message.role }} + {%- if message.content %} + {{- '\n' + message.content }} + {%- endif %} + {%- for tool_call in message.tool_calls %} + {%- if tool_call.function is defined %} + {%- set tool_call = tool_call.function %} + {%- endif %} + {{- '\n\n{"name": "' }} + {{- tool_call.name }} + {{- '", "arguments": ' }} + {{- tool_call.arguments | tojson }} + {{- '}\n' }} + {%- endfor %} + {{- '<|im_end|>\n' }} + {%- elif message.role == "tool" %} + {%- if (loop.index0 == 0) or (messages[loop.index0 - 1].role != "tool") %} + {{- '<|im_start|>user' }} + {%- endif %} + {{- '\n\n' }} + {{- message.content }} + {{- '\n' }} + {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %} + {{- '<|im_end|>\n' }} + {%- endif %} + {%- endif %} +{%- endfor %} +{%- if add_generation_prompt %} + {{- '<|im_start|>assistant\n' }} +{%- endif %} diff --git a/config.json b/config.json new file mode 100644 index 0000000..8fd59d8 --- /dev/null +++ b/config.json @@ -0,0 +1,61 @@ +{ + "architectures": [ + "Qwen2ForCausalLM" + ], + "attention_dropout": 0.0, + "bos_token_id": 151643, + "dtype": "float32", + "eos_token_id": 151645, + "hidden_act": "silu", + "hidden_size": 1536, + "initializer_range": 0.02, + "intermediate_size": 8960, + "layer_types": [ + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention", + "full_attention" + ], + "max_position_embeddings": 32768, + "max_window_layers": 21, + "model_type": "qwen2", + "num_attention_heads": 12, + "num_hidden_layers": 28, + "num_key_value_heads": 2, + "pad_token_id": null, + "rms_norm_eps": 1e-06, + "rope_parameters": { + "rope_theta": 1000000.0, + "rope_type": "default" + }, + "sliding_window": null, + "tie_word_embeddings": true, + "transformers_version": "5.14.1", + "use_cache": true, + "use_sliding_window": false, + "vocab_size": 151936 +} diff --git a/generation_config.json b/generation_config.json new file mode 100644 index 0000000..d99af67 --- /dev/null +++ b/generation_config.json @@ -0,0 +1,14 @@ +{ + "bos_token_id": 151643, + "do_sample": true, + "eos_token_id": [ + 151645, + 151643 + ], + "pad_token_id": 151643, + "repetition_penalty": 1.1, + "temperature": 0.7, + "top_k": 20, + "top_p": 0.8, + "transformers_version": "5.14.1" +} diff --git a/model.safetensors b/model.safetensors new file mode 100644 index 0000000..94f227b --- /dev/null +++ b/model.safetensors @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d63d0964ee014b73b07f73fb836b1d494d0842efa334fc9b5790334524c08d62 +size 6174895536 diff --git a/tokenizer.json b/tokenizer.json new file mode 100644 index 0000000..34510ff --- /dev/null +++ b/tokenizer.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3fd169731d2cbde95e10bf356d66d5997fd885dd8dbb6fb4684da3f23b2585d8 +size 11421892 diff --git a/tokenizer_config.json b/tokenizer_config.json new file mode 100644 index 0000000..770e41d --- /dev/null +++ b/tokenizer_config.json @@ -0,0 +1,30 @@ +{ + "add_prefix_space": false, + "backend": "tokenizers", + "bos_token": null, + "clean_up_tokenization_spaces": false, + "eos_token": "<|im_end|>", + "errors": "replace", + "extra_special_tokens": [ + "<|im_start|>", + "<|im_end|>", + "<|object_ref_start|>", + "<|object_ref_end|>", + "<|box_start|>", + "<|box_end|>", + "<|quad_start|>", + "<|quad_end|>", + "<|vision_start|>", + "<|vision_end|>", + "<|vision_pad|>", + "<|image_pad|>", + "<|video_pad|>" + ], + "is_local": false, + "local_files_only": false, + "model_max_length": 131072, + "pad_token": "<|endoftext|>", + "split_special_tokens": false, + "tokenizer_class": "Qwen2Tokenizer", + "unk_token": null +}