kentof commited on
Commit
4f560eb
·
verified ·
1 Parent(s): 32f8e7f

Upload folder using huggingface_hub

Browse files
README.md CHANGED
@@ -1,65 +1,49 @@
1
  ---
2
  base_model: Qwen/Qwen3-4B-Instruct-2507
3
  datasets:
4
- - u-10bei/structured_data_with_cot_dataset_512_v2
5
  language:
6
  - en
7
  license: apache-2.0
8
- library_name: peft
9
  pipeline_tag: text-generation
10
  tags:
11
- - qlora
12
- - lora
13
- - structured-output
 
14
  ---
15
 
16
- # SFT LoRA for Structured Output (Qwen3-4B)
17
 
18
- This repository provides a **LoRA adapter** fine-tuned from
19
- **Qwen/Qwen3-4B-Instruct-2507** using **QLoRA (4-bit, Unsloth)**.
20
 
21
- This repository contains **LoRA adapter weights only**.
22
- The base model must be loaded separately.
23
 
24
  ## Training Objective
25
-
26
- This adapter is trained to improve **structured output accuracy**
27
- (JSON / YAML / XML / TOML / CSV).
28
-
29
- Loss is applied only to the final assistant output,
30
- while intermediate reasoning (Chain-of-Thought) is masked.
31
 
32
  ## Training Configuration
33
-
34
- - Base model: Qwen/Qwen3-4B-Instruct-2507
35
- - Method: QLoRA (4-bit)
36
- - Max sequence length: 1024
37
- - Epochs: 2
38
- - Learning rate: 1e-06
39
- - LoRA: r=64, alpha=128
 
40
 
41
  ## Usage
42
-
43
  ```python
44
  from transformers import AutoModelForCausalLM, AutoTokenizer
45
- from peft import PeftModel
46
  import torch
47
 
48
- base = "Qwen/Qwen3-4B-Instruct-2507"
49
- adapter = "kentof/sft-qwen3-4b-lora"
50
-
51
- tokenizer = AutoTokenizer.from_pretrained(base)
52
- model = AutoModelForCausalLM.from_pretrained(
53
- base,
54
- torch_dtype=torch.float16,
55
- device_map="auto",
56
- )
57
- model = PeftModel.from_pretrained(model, adapter)
58
  ```
59
 
60
- ## Sources & Terms (IMPORTANT)
61
-
62
- Training data: u-10bei/structured_data_with_cot_dataset_512_v2
63
-
64
- Dataset License: MIT License. This dataset is used and distributed under the terms of the MIT License.
65
- Compliance: Users must comply with the MIT license (including copyright notice) and the base model's original terms of use.
 
1
  ---
2
  base_model: Qwen/Qwen3-4B-Instruct-2507
3
  datasets:
4
+ - u-10bei/dpo-dataset-qwen-cot
5
  language:
6
  - en
7
  license: apache-2.0
8
+ library_name: transformers
9
  pipeline_tag: text-generation
10
  tags:
11
+ - dpo
12
+ - unsloth
13
+ - qwen
14
+ - alignment
15
  ---
16
 
17
+ # DPO-aligned Qwen3-4B for Structured Output
18
 
19
+ This model is a fine-tuned version of **Qwen/Qwen3-4B-Instruct-2507** using **Direct Preference Optimization (DPO)** via the **Unsloth** library.
 
20
 
21
+ This repository contains the **full-merged 16-bit weights**. No adapter loading is required.
 
22
 
23
  ## Training Objective
24
+ This model has been optimized using DPO to align its responses with preferred outputs, focusing on improving reasoning (Chain-of-Thought) and structured response quality.
 
 
 
 
 
25
 
26
  ## Training Configuration
27
+ - **Base model**: Qwen/Qwen3-4B-Instruct-2507
28
+ - **SFT Adapter**: lora_structeval_t_qwen3_4b (merged before DPO)
29
+ - **Method**: DPO (Direct Preference Optimization)
30
+ - **Epochs**: 1
31
+ - **Learning rate**: 1e-07
32
+ - **Beta**: 0.1
33
+ - **Max sequence length**: 1024
34
+ - **LoRA Config**: r=8, alpha=16 (merged into base)
35
 
36
  ## Usage
 
37
  ```python
38
  from transformers import AutoModelForCausalLM, AutoTokenizer
 
39
  import torch
40
 
41
+ model_id = "kentof/dpo-qwen-cot-merged"
42
+ tokenizer = AutoTokenizer.from_pretrained(model_id)
43
+ model = AutoModelForCausalLM.from_pretrained(model_id, torch_dtype=torch.float16, device_map="auto")
 
 
 
 
 
 
 
44
  ```
45
 
46
+ ## Sources & License (IMPORTANT)
47
+ * **Training Data**: generate/data/data_dpo.json
48
+ * **License**: MIT License.
49
+ * **Compliance**: Users must follow the original base model's license terms.
 
 
adapter_config.json CHANGED
@@ -5,7 +5,7 @@
5
  "parent_library": "transformers.models.qwen3.modeling_qwen3",
6
  "unsloth_fixed": true
7
  },
8
- "base_model_name_or_path": "unsloth/qwen3-4b-instruct-2507-unsloth-bnb-4bit",
9
  "bias": "none",
10
  "fan_in_fan_out": false,
11
  "inference_mode": true,
@@ -24,13 +24,13 @@
24
  "rank_pattern": {},
25
  "revision": null,
26
  "target_modules": [
27
- "o_proj",
28
- "down_proj",
29
  "gate_proj",
 
 
 
30
  "v_proj",
31
- "q_proj",
32
- "up_proj",
33
- "k_proj"
34
  ],
35
  "task_type": "CAUSAL_LM",
36
  "use_dora": false,
 
5
  "parent_library": "transformers.models.qwen3.modeling_qwen3",
6
  "unsloth_fixed": true
7
  },
8
+ "base_model_name_or_path": "Qwen/Qwen3-4B-Instruct-2507",
9
  "bias": "none",
10
  "fan_in_fan_out": false,
11
  "inference_mode": true,
 
24
  "rank_pattern": {},
25
  "revision": null,
26
  "target_modules": [
27
+ "q_proj",
 
28
  "gate_proj",
29
+ "k_proj",
30
+ "down_proj",
31
+ "o_proj",
32
  "v_proj",
33
+ "up_proj"
 
 
34
  ],
35
  "task_type": "CAUSAL_LM",
36
  "use_dora": false,
adapter_model.safetensors CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:69e5c96c49ab57f8c0bc1a3906b42981984b3cbd8035c7c9c8c9182832407444
3
  size 528550256
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:53cf1c8bc09d85b5536d70eb7786f9c4742a9eb2a2aa84c1381083846bdec6f2
3
  size 528550256
chat_template.jinja CHANGED
@@ -1,80 +1,47 @@
1
  {%- if tools %}
2
  {{- '<|im_start|>system\n' }}
3
- {%- if messages[0].role == 'system' %}
4
- {{- messages[0].content + '\n\n' }}
 
 
5
  {%- endif %}
6
- {{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within <tools></tools> XML tags:\n<tools>" }}
7
  {%- for tool in tools %}
8
  {{- "\n" }}
9
  {{- tool | tojson }}
10
  {%- endfor %}
11
  {{- "\n</tools>\n\nFor each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\n<tool_call>\n{\"name\": <function-name>, \"arguments\": <args-json-object>}\n</tool_call><|im_end|>\n" }}
12
  {%- else %}
13
- {%- if messages[0].role == 'system' %}
14
- {{- '<|im_start|>system\n' + messages[0].content + '<|im_end|>\n' }}
 
 
15
  {%- endif %}
16
  {%- endif %}
17
- {%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %}
18
- {%- for message in messages[::-1] %}
19
- {%- set index = (messages|length - 1) - loop.index0 %}
20
- {%- if ns.multi_step_tool and message.role == "user" and message.content is string and not(message.content.startswith('<tool_response>') and message.content.endswith('</tool_response>')) %}
21
- {%- set ns.multi_step_tool = false %}
22
- {%- set ns.last_query_index = index %}
23
- {%- endif %}
24
- {%- endfor %}
25
  {%- for message in messages %}
26
- {%- if message.content is string %}
27
- {%- set content = message.content %}
28
- {%- else %}
29
- {%- set content = '' %}
30
- {%- endif %}
31
- {%- if (message.role == "user") or (message.role == "system" and not loop.first) %}
32
- {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }}
33
  {%- elif message.role == "assistant" %}
34
- {%- set reasoning_content = '' %}
35
- {%- if message.reasoning_content is string %}
36
- {%- set reasoning_content = message.reasoning_content %}
37
- {%- else %}
38
- {%- if '</think>' in content %}
39
- {%- set reasoning_content = content.split('</think>')[0].rstrip('\n').split('<think>')[-1].lstrip('\n') %}
40
- {%- set content = content.split('</think>')[-1].lstrip('\n') %}
41
- {%- endif %}
42
  {%- endif %}
43
- {%- if loop.index0 > ns.last_query_index %}
44
- {%- if loop.last or (not loop.last and reasoning_content) %}
45
- {{- '<|im_start|>' + message.role + '\n<think>\n' + reasoning_content.strip('\n') + '\n</think>\n\n' + content.lstrip('\n') }}
46
- {%- else %}
47
- {{- '<|im_start|>' + message.role + '\n' + content }}
48
  {%- endif %}
49
- {%- else %}
50
- {{- '<|im_start|>' + message.role + '\n' + content }}
51
- {%- endif %}
52
- {%- if message.tool_calls %}
53
- {%- for tool_call in message.tool_calls %}
54
- {%- if (loop.first and content) or (not loop.first) %}
55
- {{- '\n' }}
56
- {%- endif %}
57
- {%- if tool_call.function %}
58
- {%- set tool_call = tool_call.function %}
59
- {%- endif %}
60
- {{- '<tool_call>\n{"name": "' }}
61
- {{- tool_call.name }}
62
- {{- '", "arguments": ' }}
63
- {%- if tool_call.arguments is string %}
64
- {{- tool_call.arguments }}
65
- {%- else %}
66
- {{- tool_call.arguments | tojson }}
67
- {%- endif %}
68
- {{- '}\n</tool_call>' }}
69
- {%- endfor %}
70
- {%- endif %}
71
  {{- '<|im_end|>\n' }}
72
  {%- elif message.role == "tool" %}
73
- {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %}
74
- {{- '<|im_start|>user' }}
75
  {%- endif %}
76
  {{- '\n<tool_response>\n' }}
77
- {{- content }}
78
  {{- '\n</tool_response>' }}
79
  {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %}
80
  {{- '<|im_end|>\n' }}
@@ -83,4 +50,4 @@
83
  {%- endfor %}
84
  {%- if add_generation_prompt %}
85
  {{- '<|im_start|>assistant\n' }}
86
- {%- endif %}
 
1
  {%- if tools %}
2
  {{- '<|im_start|>system\n' }}
3
+ {%- if messages[0]['role'] == 'system' %}
4
+ {{- messages[0]['content'] }}
5
+ {%- else %}
6
+ {{- 'You are Qwen, created by Alibaba Cloud. You are a helpful assistant.' }}
7
  {%- endif %}
8
+ {{- "\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 <tools></tools> XML tags:\n<tools>" }}
9
  {%- for tool in tools %}
10
  {{- "\n" }}
11
  {{- tool | tojson }}
12
  {%- endfor %}
13
  {{- "\n</tools>\n\nFor each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\n<tool_call>\n{\"name\": <function-name>, \"arguments\": <args-json-object>}\n</tool_call><|im_end|>\n" }}
14
  {%- else %}
15
+ {%- if messages[0]['role'] == 'system' %}
16
+ {{- '<|im_start|>system\n' + messages[0]['content'] + '<|im_end|>\n' }}
17
+ {%- else %}
18
+ {{- '<|im_start|>system\nYou are Qwen, created by Alibaba Cloud. You are a helpful assistant.<|im_end|>\n' }}
19
  {%- endif %}
20
  {%- endif %}
 
 
 
 
 
 
 
 
21
  {%- for message in messages %}
22
+ {%- if (message.role == "user") or (message.role == "system" and not loop.first) or (message.role == "assistant" and not message.tool_calls) %}
23
+ {{- '<|im_start|>' + message.role + '\n' + message.content + '<|im_end|>' + '\n' }}
 
 
 
 
 
24
  {%- elif message.role == "assistant" %}
25
+ {{- '<|im_start|>' + message.role }}
26
+ {%- if message.content %}
27
+ {{- '\n' + message.content }}
 
 
 
 
 
28
  {%- endif %}
29
+ {%- for tool_call in message.tool_calls %}
30
+ {%- if tool_call.function is defined %}
31
+ {%- set tool_call = tool_call.function %}
 
 
32
  {%- endif %}
33
+ {{- '\n<tool_call>\n{"name": "' }}
34
+ {{- tool_call.name }}
35
+ {{- '", "arguments": ' }}
36
+ {{- tool_call.arguments | tojson }}
37
+ {{- '}\n</tool_call>' }}
38
+ {%- endfor %}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  {{- '<|im_end|>\n' }}
40
  {%- elif message.role == "tool" %}
41
+ {%- if (loop.index0 == 0) or (messages[loop.index0 - 1].role != "tool") %} {{- '<|im_start|>user' }}
 
42
  {%- endif %}
43
  {{- '\n<tool_response>\n' }}
44
+ {{- message.content }}
45
  {{- '\n</tool_response>' }}
46
  {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %}
47
  {{- '<|im_end|>\n' }}
 
50
  {%- endfor %}
51
  {%- if add_generation_prompt %}
52
  {{- '<|im_start|>assistant\n' }}
53
+ {%- endif %}
tokenizer_config.json CHANGED
@@ -233,7 +233,7 @@
233
  "extra_special_tokens": {},
234
  "model_max_length": 262144,
235
  "pad_token": "<|vision_pad|>",
236
- "padding_side": "right",
237
  "split_special_tokens": false,
238
  "tokenizer_class": "Qwen2Tokenizer",
239
  "unk_token": null
 
233
  "extra_special_tokens": {},
234
  "model_max_length": 262144,
235
  "pad_token": "<|vision_pad|>",
236
+ "padding_side": "left",
237
  "split_special_tokens": false,
238
  "tokenizer_class": "Qwen2Tokenizer",
239
  "unk_token": null
training_args.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ce087cbc9637eff2c7d6cb16f84b3dd9cfc89ef4b4d609541a720a38afa12a3b
3
+ size 6801