sdananya commited on
Commit
8e5a0bc
Β·
verified Β·
1 Parent(s): f332de3

Update README: subfolder-based layout, document checkpoints

Browse files
Files changed (1) hide show
  1. README.md +81 -44
README.md CHANGED
@@ -1,73 +1,110 @@
1
  ---
2
- language: en
3
- tags:
4
- - character-training
5
- - open-character-training
6
- - loving
7
- - lora
8
- - merged-adapter
9
  base_model: Qwen/Qwen2.5-7B-Instruct
10
  library_name: peft
 
 
 
 
 
 
11
  ---
12
 
13
  # qwen-2.5-7b-it-loving-merged
14
 
15
- Combined character-training LoRA for Qwen2.5-7B-Instruct on the `loving` constitution,
16
- produced by linearly blending the DPO distillation adapter and the SFT introspection
17
- adapter β€” matching the canonical [Open Character Training](https://arxiv.org/abs/2511.01689)
18
- publish recipe in [`tools/merge_loras.py`](https://github.com/sdananya/OpenCharacterTraining/blob/main/tools/merge_loras.py).
 
19
 
20
- ```
21
- W_persona = 1.0 Β· W_DPO + 0.25 Β· W_SFT
22
- ```
 
 
 
23
 
24
- The result is a single rank-64 LoRA whose reference frame is the **vanilla base model**
25
- (`Qwen/Qwen2.5-7B-Instruct`), so it can be loaded directly with PEFT against the
26
- upstream HF base β€” no folding step required.
27
 
28
- ## Why a merged adapter?
 
 
 
 
 
 
 
 
29
 
30
- The SFT introspection LoRA in [`sdananya/qwen-2.5-7b-it-loving`](https://huggingface.co/sdananya/qwen-2.5-7b-it-loving)
31
- was trained on top of the **DPO-folded** base (`base + DPO_LoRA` merged), so its
32
- weight delta only makes sense in that reference frame. Loading the standalone SFT
33
- adapter against vanilla `Qwen2.5-7B-Instruct` applies the delta in the wrong frame
34
- and produces degraded outputs.
35
 
36
- This repo packages the correct deployable artifact: a single LoRA that *does* live
37
- in the vanilla-base frame, by combining DPO (full strength) with a 0.25-weighted
38
- SFT introspection contribution.
39
 
40
- ## Usage
41
 
42
  ```python
43
  from peft import PeftModel
44
  from transformers import AutoModelForCausalLM, AutoTokenizer
45
- import torch
46
 
47
  base = AutoModelForCausalLM.from_pretrained(
48
- "Qwen/Qwen2.5-7B-Instruct", torch_dtype=torch.bfloat16, device_map="auto"
 
 
 
 
 
 
 
 
 
49
  )
50
- tok = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-7B-Instruct")
51
- model = PeftModel.from_pretrained(base, "sdananya/qwen-2.5-7b-it-loving-merged")
52
  ```
53
 
54
- ## Training pipeline (paper-equivalent)
 
 
 
 
 
 
55
 
56
- 1. **DPO distillation** on the `loving` DPO dataset β†’ rank-64 LoRA over base.
57
- 2. **Fold** the DPO LoRA into base β†’ distilled checkpoint.
58
- 3. **SFT introspection** on self-reflection + self-interaction data β†’ rank-64 LoRA over the folded base.
59
- 4. **Merge** with weights `[1.0, 0.25]` against vanilla base β†’ this adapter.
 
60
 
61
- Hyperparameters: rank=64, alpha=128, lr=5e-5, warmup=0.1, max_epochs=1, batch=32,
62
- DeepSpeed ZeRO-2, bf16. See [the OCT repo](https://github.com/sdananya/OpenCharacterTraining)
63
- for full configs.
64
 
65
- ## Related artifacts in this org
 
 
 
 
66
 
67
- - [`sdananya/qwen-2.5-7b-it-loving`](https://huggingface.co/sdananya/qwen-2.5-7b-it-loving) β€” separate `dpo-final/` and `introspection-final/` folders. The DPO adapter is correctly framed; the introspection adapter alone is **not** (see above).
68
- - [`sdananya/qwen-2.5-7b-it-loving-no-dpo`](https://huggingface.co/sdananya/qwen-2.5-7b-it-loving-no-dpo) β€” ablation: SFT introspection trained directly on vanilla base, no DPO.
69
- - [`sdananya/qwen-2.5-7b-it-loving-dpo200`](https://huggingface.co/sdananya/qwen-2.5-7b-it-loving-dpo200) β€” ablation: SFT introspection seeded from a partial (200-step) DPO checkpoint.
 
 
 
 
 
 
 
70
 
71
  ## Citation
72
 
73
- Based on [Open Character Training](https://arxiv.org/abs/2511.01689).
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ license: cc-by-nc-sa-4.0
 
 
 
 
 
 
3
  base_model: Qwen/Qwen2.5-7B-Instruct
4
  library_name: peft
5
+ tags:
6
+ - lora
7
+ - peft
8
+ - character-training
9
+ - open-character-training
10
+ - qwen
11
  ---
12
 
13
  # qwen-2.5-7b-it-loving-merged
14
 
15
+ Reproduction of the **loving** persona from
16
+ [Open Character Training](https://arxiv.org/abs/2511.01689)
17
+ (Maiya et al., 2025), trained on top of `Qwen/Qwen2.5-7B-Instruct` using the
18
+ public [maiush/OpenCharacterTraining](https://github.com/maiush/OpenCharacterTraining)
19
+ pipeline and dataset.
20
 
21
+ This repository contains **correctly-merged** LoRA adapters at every published
22
+ checkpoint. The adapters in the original `sdananya/qwen-2.5-7b-it-loving` repo
23
+ were unmerged SFT LoRAs trained against the DPO-folded base but uploaded with
24
+ an `adapter_config.json` claiming the vanilla base β€” silently degrading
25
+ inference. This repo fixes that by re-merging both training-stage LoRAs into
26
+ a single rank-64 adapter against vanilla Qwen for every checkpoint.
27
 
28
+ ## Repository layout
 
 
29
 
30
+ ```
31
+ sdananya/qwen-2.5-7b-it-loving-merged/
32
+ β”œβ”€β”€ dpo-final/ ← DPO LoRA (rank-64, against vanilla Qwen)
33
+ β”œβ”€β”€ dpo-step125/ ... dpo-step250/ ← 6 intermediate DPO checkpoints
34
+ β”œβ”€β”€ introspection-final/ ← merged final: 1.0Β·Ξ”W_DPO_final + 0.25Β·Ξ”W_SFT_final
35
+ └── introspection-step225/ ... introspection-step350/
36
+ ← 6 merged intermediate SFT checkpoints,
37
+ each = 1.0Β·Ξ”W_DPO_final + 0.25Β·Ξ”W_SFT_stepN
38
+ ```
39
 
40
+ All adapters are rank-64 LoRAs targeting `q_proj, k_proj, v_proj, o_proj,
41
+ gate_proj, up_proj, down_proj` across all 28 transformer layers.
 
 
 
42
 
43
+ ## Loading
 
 
44
 
45
+ You must specify the checkpoint as a `subfolder`:
46
 
47
  ```python
48
  from peft import PeftModel
49
  from transformers import AutoModelForCausalLM, AutoTokenizer
 
50
 
51
  base = AutoModelForCausalLM.from_pretrained(
52
+ "Qwen/Qwen2.5-7B-Instruct", torch_dtype="bfloat16"
53
+ )
54
+ model = PeftModel.from_pretrained(
55
+ base,
56
+ "sdananya/qwen-2.5-7b-it-loving-merged",
57
+ subfolder="introspection-final", # or any other checkpoint above
58
+ )
59
+ tok = AutoTokenizer.from_pretrained(
60
+ "sdananya/qwen-2.5-7b-it-loving-merged",
61
+ subfolder="introspection-final",
62
  )
 
 
63
  ```
64
 
65
+ ## Merge recipe (introspection-* checkpoints)
66
+
67
+ Each `introspection-*` folder is produced by PEFT's
68
+ `add_weighted_adapter(combination_type="linear")` applied to the DPO-final
69
+ adapter and the corresponding SFT checkpoint:
70
+
71
+ $$\Delta W_{\text{merged}} = 1.0 \cdot \Delta W_{\text{DPO-final}} + 0.25 \cdot \Delta W_{\text{SFT-stepN}}$$
72
 
73
+ The weights `[1.0, 0.25]` are taken directly from the canonical pipeline in
74
+ [`tools/merge_loras.py`](https://github.com/sdananya/OpenCharacterTraining/blob/main/tools/merge_loras.py).
75
+ The 0.25 dampening on SFT is the paper's chosen recipe β€” it preserves the
76
+ introspective character while preventing the SFT register from overpowering
77
+ normal conversation.
78
 
79
+ ## Why merging matters
 
 
80
 
81
+ The SFT introspection LoRA is trained on top of the **DPO-folded** base
82
+ (`W_base + Ξ”W_DPO`), so its low-rank factors are only meaningful in that
83
+ reference frame. Loading it directly onto vanilla `W_base` (as the original
84
+ unmerged upload did) produces a meaningful-shape but semantically wrong delta β€”
85
+ PEFT does not detect the mismatch and silently produces degraded output.
86
 
87
+ `add_weighted_adapter` re-projects both deltas into a single rank-64 subspace
88
+ anchored to vanilla `W_base`, so the published adapter's `adapter_config.json`
89
+ honestly declares its base model and PEFT applies it correctly.
90
+
91
+ ## DPO checkpoints
92
+
93
+ The `dpo-*` subfolders are byte-identical copies of the corresponding folders
94
+ in [`sdananya/qwen-2.5-7b-it-loving`](https://huggingface.co/sdananya/qwen-2.5-7b-it-loving).
95
+ DPO is trained directly on vanilla Qwen, so its reference frame is already
96
+ correct β€” no merge needed.
97
 
98
  ## Citation
99
 
100
+ ```bibtex
101
+ @misc{maiya2025opencharactertrainingshaping,
102
+ title={Open Character Training: Shaping the Persona of AI Assistants through Constitutional AI},
103
+ author={Sharan Maiya and Henning Bartsch and Nathan Lambert and Evan Hubinger},
104
+ year={2025},
105
+ eprint={2511.01689},
106
+ archivePrefix={arXiv},
107
+ primaryClass={cs.CL},
108
+ url={https://arxiv.org/abs/2511.01689},
109
+ }
110
+ ```