Downloads · 30 days
9
35% of all-time downloads
dean22029/pr_fm_gemma3_12b_adapter
pr_fm_gemma3_12b_adapter is a machine learning model from dean22029. Use it for the machine learning task on the model card, and read the license before you ship it in a product. It is set up for peft. The card lists the license as gemma.
A QLoRA adapter that predicts forced-choice conjoint outcomes: given a study context, a respondent's characteristics, and two profiles, it scores which profile that respondent chose.
Downloads · 30 days
9
35% of all-time downloads
All-time downloads
26
Public
Repo size
300 MB
Likes
0
Public
Click a slice to open those files.
.safetensors262 MB · 87%
From the Hugging Face model README
A QLoRA adapter that predicts forced-choice conjoint outcomes: given a study context, a respondent's characteristics, and two profiles, it scores which profile that respondent chose.
It is a research baseline, trained on 115 published conjoint experiments from
the preference_fm data-share bundle. It is not a general-purpose chat model
— fine-tuned on a single answer token, it only does this one task.
The base model is gated. You need a HuggingFace account that has accepted the terms on
google/gemma-3-12b-it, andhuggingface-cli login, before the example below will run.
Evaluated with one forward pass per pair (no generation), 4-bit NF4 base. The label base rate is ~50% by construction, so null log loss is 0.693 and accuracy is pair-winner accuracy. "zeroshot" is the same base model with no adapter, on the same prompts.
| Split | Run | n pairs | Accuracy | AUC | Log loss | Δ vs null | Brier |
|---|---|---|---|---|---|---|---|
test_chrono | finetuned | 58,910 | 0.582 | 0.624 | 0.6713 | 0.0218 | 0.2394 |
test_chrono | zeroshot | 58,910 | 0.548 | 0.570 | 1.3874 | -0.6943 | 0.3606 |
test_within | finetuned | 61,120 | 0.655 | 0.716 | 0.6167 | 0.0765 | 0.2143 |
test_within | zeroshot | 61,120 | 0.522 | 0.523 | 1.6709 | -0.9778 | 0.3951 |
Two things to read carefully before quoting these numbers:
test_chrono number is an average over 31 studies whose individual AUCs
range from below chance to ~0.94. Rebuilding the evaluation (see
Reproducing the data below) writes a by_experiment breakdown.| Base | google/gemma-3-12b-it |
| Method | QLoRA, 4-bit NF4 + double quant, bf16 compute |
| LoRA | r=16, alpha=32, dropout 0.05, on q,k,v,o,gate,up,down_proj |
| Optimiser | paged_adamw_8bit, lr 1e-4, cosine, warmup 3% |
| Batch | per-device 4, effective ~60 (A100 40GB, DDP) |
| Steps | 6,000 |
| Epochs completed | 0.51 |
| Max seq len | 1024 |
| Loss | masked to the assistant answer token only |
The training set is 711,617 pairs. This run saw roughly 51% of it — training was stopped by a step limit, not by convergence on a full epoch.
Validation choice accuracy over training: 0.630 @ step 2,000, 0.633 @ step 4,000, 0.640 @ step 6,000. It is flat over the last few evaluations, so the step limit is not obviously leaving accuracy on the table.
log_history.json in this repo has the step-by-step loss and eval metrics.
The adapter was trained on exactly this surface. Paraphrasing the system prompt or reordering the user block puts you out of distribution.
[system]
You simulate survey respondents in conjoint experiments. Given the study context, the respondent's characteristics, and two options, predict which option the respondent chose. Answer with exactly one letter: A or B.
[user]
Conjoint study: <description>
Country: <country>
Year: <year>
Respondent characteristics: <name: value; name: value; ...>
The respondent chose between the following two options.
Option A:
- <factor>: <level>
...
Option B:
- <factor>: <level>
...
Which option did the respondent choose?
The assistant target is a single letter, A or B.
eval_example.py in this repo is a runnable version of all of this.
logits[:, -1, :], index the
single-token ids for "A" and "B", softmax over those two -> P(A).add_generation_prompt=True, then tokenize
with add_special_tokens=False — the template already added them.padding_side="left" for batched scoring.adapter_config.json
here points at google/gemma-3-12b-it, but keep the 4-bit config above to reproduce
the numbers — loading the base in bf16 will shift them.SPLITS.md and splits_summary.csv in this repo record exactly which
experiments were trained on. The short version: training used every
experiment with experiment_year <= 2021, so a test set built with a
lower cutoff overlaps our training data. Check SPLITS.md before comparing
these numbers against a model split a different way.
These adapters were trained on prompts built from the preference_fm
conjoint data-share bundle (127 experiments; 115 usable). That bundle is not
redistributed here and is not ours to redistribute — 113 of its 127
experiments carry no declared licence, and the underlying replication archives
come from Dataverse and similar sources under their own individual terms. You
need your own copy of the bundle to rebuild the data.
The scripts are bundled in pipeline/ in this repo.
Steps 1-3 are CPU-only. Step 1 needs R with jsonlite; steps 2-3 need
tqdm and nothing else; step 4 needs the GPU stack from the example above.
# 1. experiment.rds -> JSON
Rscript pipeline/export_experiments.R --zips <bundle>/experiment_zips --out exported
# 2. reviewed covariate codebooks (optional; improves how X is verbalised)
python pipeline/make_codebooks.py --exported exported --out codebooks
# 3. prompts + splits
python pipeline/build_dataset.py --exported exported --out llm_dataset \
--cutoff-year 2021 --seed 42
# 4. score this adapter
python pipeline/evaluate_qlora.py --model <short-name> --adapter <this repo> \
--data llm_dataset/test_chrono.jsonl --out-prefix results/test_chrono
Step 3 must use --cutoff-year 2021 --seed 42 to reproduce our splits.
Compare the splits_summary.csv it writes against the one in this repo: if
they differ, the numbers on this card do not apply to your build. SPLITS.md
explains what to check.
Note that the evaluated results on this card were produced without the codebooks of step 2 — every published number uses the raw column-dummy rendering of respondent covariates.
google/gemma-3-12b-it ships a SigLIP vision tower alongside the text decoder. LoRA was applied to the text decoder only (vision and multi-modal modules are excluded by the target_modules regex), and both training and evaluation loaded the checkpoint through AutoModelForCausalLM on transformers>=4.45,<5. Newer versions may route Gemma-3 to Gemma3ForConditionalGeneration instead; if AutoModelForCausalLM does not give you the text decoder on your version, load that class explicitly — the adapter targets the text tower either way.This adapter is a modification of Gemma and its use is additionally governed by the Gemma Terms of Use.
The adapter weights are a derivative of google/gemma-3-12b-it and inherit its terms
(gemma). The training data comes from third-party replication
archives with their own individual licences and is not redistributed here.