Reubencf commited on
Commit
f14873c
·
verified ·
1 Parent(s): 61d2246

Add LoRA adapter, model card, and repointed base_model

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ tokenizer.json filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ base_model: unsloth/Llama-3.2-3B-Instruct
3
+ library_name: peft
4
+ pipeline_tag: text-generation
5
+ license: llama3.2
6
+ datasets:
7
+ - Reubencf/frontend-react-dataset-no-images
8
+ language:
9
+ - en
10
+ tags:
11
+ - lora
12
+ - peft
13
+ - react
14
+ - frontend
15
+ - code-generation
16
+ - llama-3.2
17
+ ---
18
+
19
+ # Llama-3.2-3B React LoRA
20
+
21
+ A LoRA adapter for **Llama 3.2 3B Instruct**, fine-tuned to generate React components
22
+ from natural-language descriptions. Text-only — this variant was trained on the
23
+ no-images split, so it does not take screenshots as input.
24
+
25
+ ## Usage
26
+
27
+ ```python
28
+ import torch
29
+ from transformers import AutoModelForCausalLM, AutoTokenizer
30
+ from peft import PeftModel
31
+
32
+ BASE = "unsloth/Llama-3.2-3B-Instruct"
33
+ LORA = "Reubencf/llama-3.2-3b-react-lora"
34
+
35
+ tok = AutoTokenizer.from_pretrained(BASE)
36
+ model = AutoModelForCausalLM.from_pretrained(BASE, torch_dtype=torch.bfloat16, device_map="auto")
37
+ model = PeftModel.from_pretrained(model, LORA)
38
+ model.eval()
39
+
40
+ msgs = [{"role": "user", "content": "Build a pricing table with three tiers and a monthly/yearly toggle."}]
41
+ ids = tok.apply_chat_template(msgs, add_generation_prompt=True, return_tensors="pt").to(model.device)
42
+ out = model.generate(ids, max_new_tokens=1024, temperature=0.7, top_p=0.9, do_sample=True)
43
+ print(tok.decode(out[0][ids.shape[-1]:], skip_special_tokens=True))
44
+ ```
45
+
46
+ Needs ~7 GB of VRAM in bf16. To merge the adapter into the base weights, call
47
+ `model.merge_and_unload()`.
48
+
49
+ ## Training
50
+
51
+ | | |
52
+ |---|---|
53
+ | Method | LoRA (PEFT 0.15.1) |
54
+ | Rank / alpha / dropout | 64 / 128 / 0.05 |
55
+ | Target modules | `q_proj` `k_proj` `v_proj` `o_proj` `gate_proj` `up_proj` `down_proj` |
56
+ | Trainable params | 97.3 M across 392 tensors (stored fp32, 389 MB) |
57
+ | Steps / epochs | 980 / 5, `train_batch_size=1` |
58
+ | Data | [`Reubencf/frontend-react-dataset-no-images`](https://huggingface.co/datasets/Reubencf/frontend-react-dataset-no-images) |
59
+
60
+ ### Loss
61
+
62
+ | Epoch | Eval loss |
63
+ |---|---|
64
+ | 1 | 0.556 |
65
+ | 2 | 1.581 |
66
+ | 3 | 0.541 |
67
+ | 4 | 0.529 |
68
+ | 5 | **0.525** |
69
+
70
+ Train loss fell 1.15 → 0.62 over the run.
71
+
72
+ ## Limitations
73
+
74
+ Read these before trusting the numbers above.
75
+
76
+ - **The eval set is ~3 examples.** At that size the eval-loss column is close to
77
+ noise, and the epoch-2 spike to 1.58 is not interpretable. There is no held-out
78
+ benchmark and no human evaluation of the generated components.
79
+ - **Probably trained on a subset.** 196 steps/epoch at batch size 1 accounts for
80
+ ~196 of the dataset's 1000 rows. `total_flos` (1.797e19) implies ~950 tokens per
81
+ example, which is consistent with that reading rather than with gradient
82
+ accumulation over the full set.
83
+ - **Output is not validated.** Generated JSX is not compiled, linted, or rendered
84
+ during training or eval. Expect to fix imports and hallucinated component APIs.
85
+ - **Small base model.** 3B params — weaker at multi-file work, state management,
86
+ and long components than larger code models.
87
+
88
+ ## Base model
89
+
90
+ The adapter's `base_model_name_or_path` originally pointed at
91
+ `togethercomputer/Meta-Llama-3.2-3B-Instruct-Reference__TOG__FT`, a Together
92
+ training-internal reference that does not resolve on the Hub. It is repointed to
93
+ `unsloth/Llama-3.2-3B-Instruct`, an ungated mirror of the same weights, so the
94
+ adapter loads without a gate request. `meta-llama/Llama-3.2-3B-Instruct` is the
95
+ canonical (manually gated) source and works identically if you have access.
96
+
97
+ Licensed under the Llama 3.2 Community License, inherited from the base model.
adapter_config.json ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "alpha_pattern": {},
3
+ "auto_mapping": null,
4
+ "base_model_name_or_path": "unsloth/Llama-3.2-3B-Instruct",
5
+ "bias": "none",
6
+ "corda_config": null,
7
+ "eva_config": null,
8
+ "exclude_modules": [],
9
+ "fan_in_fan_out": false,
10
+ "inference_mode": true,
11
+ "init_lora_weights": true,
12
+ "layer_replication": null,
13
+ "layers_pattern": null,
14
+ "layers_to_transform": null,
15
+ "loftq_config": {},
16
+ "lora_alpha": 128,
17
+ "lora_bias": false,
18
+ "lora_dropout": 0.05000000074505806,
19
+ "megatron_config": null,
20
+ "megatron_core": "megatron.core",
21
+ "modules_to_save": null,
22
+ "peft_type": "LORA",
23
+ "r": 64,
24
+ "rank_pattern": {},
25
+ "revision": null,
26
+ "target_modules": [
27
+ "down_proj",
28
+ "q_proj",
29
+ "gate_proj",
30
+ "v_proj",
31
+ "o_proj",
32
+ "k_proj",
33
+ "up_proj"
34
+ ],
35
+ "task_type": "CAUSAL_LM",
36
+ "trainable_token_indices": null,
37
+ "use_dora": false,
38
+ "use_rslora": false
39
+ }
adapter_model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0c5212462d657d59b6b76180cd064fa0b762ace4808e2be615ac751d3b8d7d13
3
+ size 389074464
chat_template.jinja ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {{- bos_token }}
2
+ {%- if custom_tools is defined %}
3
+ {%- set tools = custom_tools %}
4
+ {%- endif %}
5
+ {%- if not tools_in_user_message is defined %}
6
+ {%- set tools_in_user_message = true %}
7
+ {%- endif %}
8
+ {%- if not date_string is defined %}
9
+ {%- if strftime_now is defined %}
10
+ {%- set date_string = strftime_now("%d %b %Y") %}
11
+ {%- else %}
12
+ {%- set date_string = "26 Jul 2024" %}
13
+ {%- endif %}
14
+ {%- endif %}
15
+ {%- if not tools is defined %}
16
+ {%- set tools = none %}
17
+ {%- endif %}
18
+
19
+ {#- This block extracts the system message, so we can slot it into the right place. #}
20
+ {%- if messages[0]['role'] == 'system' %}
21
+ {%- set system_message = messages[0]['content']|trim %}
22
+ {%- set messages = messages[1:] %}
23
+ {%- else %}
24
+ {%- set system_message = "" %}
25
+ {%- endif %}
26
+
27
+ {#- System message #}
28
+ {{- "<|start_header_id|>system<|end_header_id|>\n\n" }}
29
+ {%- if tools is not none %}
30
+ {{- "Environment: ipython\n" }}
31
+ {%- endif %}
32
+ {{- "Cutting Knowledge Date: December 2023\n" }}
33
+ {{- "Today Date: " + date_string + "\n\n" }}
34
+ {%- if tools is not none and not tools_in_user_message %}
35
+ {{- "You have access to the following functions. To call a function, please respond with JSON for a function call." }}
36
+ {{- 'Respond in the format {"name": function name, "parameters": dictionary of argument name and its value}.' }}
37
+ {{- "Do not use variables.\n\n" }}
38
+ {%- for t in tools %}
39
+ {{- t | tojson(indent=4) }}
40
+ {{- "\n\n" }}
41
+ {%- endfor %}
42
+ {%- endif %}
43
+ {{- system_message }}
44
+ {{- "<|eot_id|>" }}
45
+
46
+ {#- Custom tools are passed in a user message with some extra guidance #}
47
+ {%- if tools_in_user_message and not tools is none %}
48
+ {#- Extract the first user message so we can plug it in here #}
49
+ {%- if messages | length != 0 %}
50
+ {%- set first_user_message = messages[0]['content']|trim %}
51
+ {%- set messages = messages[1:] %}
52
+ {%- else %}
53
+ {{- raise_exception("Cannot put tools in the first user message when there's no first user message!") }}
54
+ {%- endif %}
55
+ {{- '<|start_header_id|>user<|end_header_id|>\n\n' -}}
56
+ {{- "Given the following functions, please respond with a JSON for a function call " }}
57
+ {{- "with its proper arguments that best answers the given prompt.\n\n" }}
58
+ {{- 'Respond in the format {"name": function name, "parameters": dictionary of argument name and its value}.' }}
59
+ {{- "Do not use variables.\n\n" }}
60
+ {%- for t in tools %}
61
+ {{- t | tojson(indent=4) }}
62
+ {{- "\n\n" }}
63
+ {%- endfor %}
64
+ {{- first_user_message + "<|eot_id|>"}}
65
+ {%- endif %}
66
+
67
+ {%- for message in messages %}
68
+ {%- if not (message.role == 'ipython' or message.role == 'tool' or 'tool_calls' in message) %}
69
+ {{- '<|start_header_id|>' + message['role'] + '<|end_header_id|>\n\n'+ message['content'] | trim + '<|eot_id|>' }}
70
+ {%- elif 'tool_calls' in message %}
71
+ {%- if not message.tool_calls|length == 1 %}
72
+ {{- raise_exception("This model only supports single tool-calls at once!") }}
73
+ {%- endif %}
74
+ {%- set tool_call = message.tool_calls[0].function %}
75
+ {{- '<|start_header_id|>assistant<|end_header_id|>\n\n' -}}
76
+ {{- '{"name": "' + tool_call.name + '", ' }}
77
+ {{- '"parameters": ' }}
78
+ {{- tool_call.arguments | tojson }}
79
+ {{- "}" }}
80
+ {{- "<|eot_id|>" }}
81
+ {%- elif message.role == "tool" or message.role == "ipython" %}
82
+ {{- "<|start_header_id|>ipython<|end_header_id|>\n\n" }}
83
+ {%- if message.content is mapping or message.content is iterable %}
84
+ {{- message.content | tojson }}
85
+ {%- else %}
86
+ {{- message.content }}
87
+ {%- endif %}
88
+ {{- "<|eot_id|>" }}
89
+ {%- endif %}
90
+ {%- endfor %}
91
+ {%- if add_generation_prompt %}
92
+ {{- '<|start_header_id|>assistant<|end_header_id|>\n\n' }}
93
+ {%- endif %}
config.json ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "LlamaForCausalLM"
4
+ ],
5
+ "attention_bias": false,
6
+ "attention_dropout": 0.0,
7
+ "bos_token_id": 128000,
8
+ "dtype": "bfloat16",
9
+ "eos_token_id": 128009,
10
+ "head_dim": 128,
11
+ "hidden_act": "silu",
12
+ "hidden_size": 3072,
13
+ "initializer_range": 0.02,
14
+ "intermediate_size": 8192,
15
+ "max_position_embeddings": 131072,
16
+ "mlp_bias": false,
17
+ "model_type": "llama",
18
+ "num_attention_heads": 24,
19
+ "num_hidden_layers": 28,
20
+ "num_key_value_heads": 8,
21
+ "pad_token_id": 128009,
22
+ "pretraining_tp": 1,
23
+ "rms_norm_eps": 1e-05,
24
+ "rope_parameters": {
25
+ "factor": 32.0,
26
+ "high_freq_factor": 4.0,
27
+ "low_freq_factor": 1.0,
28
+ "original_max_position_embeddings": 8192,
29
+ "rope_theta": 500000.0,
30
+ "rope_type": "llama3"
31
+ },
32
+ "tie_word_embeddings": true,
33
+ "transformers_version": "5.13.0",
34
+ "use_cache": false,
35
+ "vocab_size": 128256,
36
+ "torch_dtype": "bfloat16"
37
+ }
special_tokens_map.json ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ {
2
+ "bos_token": "<|begin_of_text|>",
3
+ "eos_token": "<|eot_id|>",
4
+ "pad_token": "<|eot_id|>"
5
+ }
tokenizer.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6b9e4e7fb171f92fd137b777cc2714bf87d11576700a1dcd7a399e7bbe39537b
3
+ size 17209920
tokenizer_config.json ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "bos_token": "<|begin_of_text|>",
3
+ "clean_up_tokenization_spaces": true,
4
+ "eos_token": "<|eot_id|>",
5
+ "model_input_names": [
6
+ "input_ids",
7
+ "attention_mask"
8
+ ],
9
+ "model_max_length": 131072,
10
+ "pad_token": "<|eot_id|>",
11
+ "padding_side": "right",
12
+ "tokenizer_class": "PreTrainedTokenizerFast"
13
+ }
trainer_state.json ADDED
The diff for this file is too large to render. See raw diff