CARDS-Wind-Gemma4-31B

Gemma 4 31B fine-tuned to detect and classify opposition to wind energy under the three-level CARDS-Wind taxonomy. LoRA-trained on human-annotated wind-opposition passages (augmented with Opus-generated reasoning traces and stratified synthetic data), then merged back into the base weights. BF16 checkpoint; multimodal (image + text).

Deploying? Use the FP8 variant C3DS/CARDS-Wind-Gemma4-31B-FP8 โ€” ~33 GB vs ~62 GB here, near-lossless, fits a single 80GB GPU with room for KV cache.

What it does

Given a passage (news, comment, forum post, council minutes, social media), the model emits a three-level classification:

  1. opposition_detected โ€” binary: does the text oppose, dislike, or express skepticism of wind energy? (sarcasm and tonal opposition count)
  2. frames โ€” which of 8 high-level argument frames (N_1โ€“N_8, or N_0 fallback) the text invokes.
  3. claims โ€” the specific assertions (C_* codes, ~58-code hierarchical codebook) argued within those frames.

When opposition_detected is false, frames and claims are empty.

Results

Evaluated on the held-out Wind test set (773 rows, 436 opposition-only; Macro/Micro F1 restricted to gold codes with support โ‰ฅ 3, hallucinated codes dropped). Compared against the paper's best fine-tuned Qwen model and two frontier APIs:

Metric Gemma4-31B FT (this model) Windy-Qwen3.5-27B FT Claude Opus 4.7 GPT-5.5
Detection โ€” Precision 0.871 0.877 0.896 0.927
Detection โ€” Recall 0.897 0.920 0.890 0.846
Detection โ€” F1 0.884 0.898 0.893 0.885
Samples F1 โ€” frames (all rows) 0.773 0.787 0.791 0.792
Samples F1 โ€” frames (opp. only) 0.730 0.751 0.734 0.697
Samples F1 โ€” claims (all rows) 0.741 0.755 0.754 0.745
Samples F1 โ€” claims (opp. only) 0.674 0.694 0.667 0.614
Macro F1 โ€” frames (opp. only) 0.692 0.664 0.692 0.660
Macro F1 โ€” claims (opp. only) 0.632 0.648 0.635 0.608
Micro F1 โ€” frames (opp. only) 0.788 0.796 0.788 0.696
Micro F1 โ€” claims (opp. only) 0.728 0.735 0.724 0.696
Parse failures 0 / 773 0 / 773 1 / 773 2 / 773

Competitive with frontier APIs at a fraction of the inference cost โ€” best or tied-best Macro F1 on frames (opposition-only) alongside Claude Opus 4.7, and zero parse failures.

Usage

The system prompt and three-level output format are bundled in the FP8 repo as wind_prompts.json. The fine-tune was trained with the slim system instruction โ€” use slim_system_instruction.

With vLLM

vllm serve C3DS/CARDS-Wind-Gemma4-31B \
  --port 8000 \
  --max-model-len 8192 \
  --enable-prefix-caching \
  --served-model-name CARDS-Wind-Gemma4-31B
import json
from huggingface_hub import hf_hub_download
from openai import OpenAI

prompts = json.load(open(hf_hub_download("C3DS/CARDS-Wind-Gemma4-31B-FP8", "wind_prompts.json")))
system_instruction = prompts["slim_system_instruction"]

client = OpenAI(base_url="http://localhost:8000/v1", api_key="dummy")

def classify(text):
    resp = client.chat.completions.create(
        model="CARDS-Wind-Gemma4-31B",
        messages=[
            {"role": "system", "content": system_instruction},
            {"role": "user",   "content": f"### Text:\n{text}"},
        ],
        temperature=0,
        max_tokens=4000,
        extra_body={"chat_template_kwargs": {"enable_thinking": True}},
    )
    return resp.choices[0].message.content

print(classify("These bird-killing turbines will spike our electricity bills and never pay for themselves."))

The model reasons inside <think>โ€ฆ</think> and then emits a YAML block. To parse: take the content after </think> and read the opposition_detected, frames, and claims fields:

opposition_detected: true
frames:
  - N_1
claims:
  - C_7_0

Thinking must be enabled. Gemma 4 chat templates default enable_thinking off (they pre-fill an empty thought channel); always pass chat_template_kwargs={"enable_thinking": true} or the model classifies without its reasoning chain.

Multimodal โ€” image + text

Gemma 4 is a vision-language model, so this fine-tune also classifies claims depicted in images (memes, screenshots, posters), with or without a caption. Serve with multimodal flags and pass an image_url content part alongside the system prompt:

vllm serve C3DS/CARDS-Wind-Gemma4-31B \
  --port 8000 --max-model-len 8192 --trust-remote-code \
  --limit-mm-per-prompt image=4 --enable-prefix-caching \
  --served-model-name CARDS-Wind-Gemma4-31B

Training

  • Base model: google/gemma-4-31b family (Gemma 4, Gemma4ForConditionalGeneration)
  • Method: LoRA (rank 16, ฮฑ 16, dropout 0) on q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj, merged into base weights
  • Dataset: iRanadheer/wind-opposition-sft โ€” human-annotated wind-opposition passages augmented with Opus-generated RECoT reasoning traces and stratified synthetic positives / near-miss negatives
  • Framework: Unsloth + TRL SFTTrainer
  • Hyperparameters: 3 epochs, gradient_accumulation_steps=8, lr=2e-4, cosine schedule, 10 warmup steps, max_seq_length=4096, adamw_8bit, bf16, best checkpoint selected on eval loss

Limitations

  • Thinking tokens. Training used enable_thinking=True. Gemma 4 defaults it off โ€” always pass chat_template_kwargs={"enable_thinking": true}, and reserve token budget for the reasoning trace before the final YAML block.
  • Domain. Tuned specifically for wind-energy opposition under the CARDS-Wind taxonomy; it is not a general climate-claim classifier (see the CARDS sibling models for that).

Citation

@article{coan2026llm,
  title     = {Large language model reveals an increase in climate contrarian speech in the United States Congress},
  author    = {Coan, Travis G. and Malla, Ranadheer and Nanko, Mirjam O. and Kattrup, William and Roberts, J. Timmons and Cook, John and Boussalis, Constantine},
  journal   = {Communications Sustainability},
  volume    = {1},
  number    = {1},
  pages     = {37},
  year      = {2026},
  publisher = {Nature Publishing Group},
  doi       = {10.1038/s44458-025-00029-z},
  url       = {https://www.nature.com/articles/s44458-025-00029-z}
}

License

Apache 2.0, inherited from the base Gemma 4 model.

Downloads last month
22
Safetensors
Model size
31B params
Tensor type
BF16
ยท
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support

Model tree for C3DS/CARDS-Wind-Gemma4-31B

Adapters
2 models