初始化项目,由ModelHub XC社区提供模型

Model: jsl5710/Shield-Qwen3Guard-Gen-0.6B-Full-FT-CE
Source: Original Platform
This commit is contained in:
ModelHub XC
2026-08-30 09:24:16 +08:00
commit 27594e1d0c
10 changed files with 447 additions and 0 deletions

36
.gitattributes vendored Normal file
View File

@@ -0,0 +1,36 @@
*.7z filter=lfs diff=lfs merge=lfs -text
*.arrow filter=lfs diff=lfs merge=lfs -text
*.bin filter=lfs diff=lfs merge=lfs -text
*.bz2 filter=lfs diff=lfs merge=lfs -text
*.ckpt filter=lfs diff=lfs merge=lfs -text
*.ftz filter=lfs diff=lfs merge=lfs -text
*.gz filter=lfs diff=lfs merge=lfs -text
*.h5 filter=lfs diff=lfs merge=lfs -text
*.joblib filter=lfs diff=lfs merge=lfs -text
*.lfs.* filter=lfs diff=lfs merge=lfs -text
*.mlmodel filter=lfs diff=lfs merge=lfs -text
*.model filter=lfs diff=lfs merge=lfs -text
*.msgpack filter=lfs diff=lfs merge=lfs -text
*.npy filter=lfs diff=lfs merge=lfs -text
*.npz filter=lfs diff=lfs merge=lfs -text
*.onnx filter=lfs diff=lfs merge=lfs -text
*.ot filter=lfs diff=lfs merge=lfs -text
*.parquet filter=lfs diff=lfs merge=lfs -text
*.pb filter=lfs diff=lfs merge=lfs -text
*.pickle filter=lfs diff=lfs merge=lfs -text
*.pkl filter=lfs diff=lfs merge=lfs -text
*.pt filter=lfs diff=lfs merge=lfs -text
*.pth filter=lfs diff=lfs merge=lfs -text
*.rar filter=lfs diff=lfs merge=lfs -text
*.safetensors filter=lfs diff=lfs merge=lfs -text
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
*.tar.* filter=lfs diff=lfs merge=lfs -text
*.tar filter=lfs diff=lfs merge=lfs -text
*.tflite filter=lfs diff=lfs merge=lfs -text
*.tgz filter=lfs diff=lfs merge=lfs -text
*.wasm filter=lfs diff=lfs merge=lfs -text
*.xz filter=lfs diff=lfs merge=lfs -text
*.zip filter=lfs diff=lfs merge=lfs -text
*.zst filter=lfs diff=lfs merge=lfs -text
*tfevents* filter=lfs diff=lfs merge=lfs -text
tokenizer.json filter=lfs diff=lfs merge=lfs -text

147
README.md Normal file
View File

@@ -0,0 +1,147 @@
---
license: apache-2.0
base_model: Qwen/Qwen3Guard-Gen-0.6B
tags:
- dia-guard
- shield
- safety
- dialect
- full-ft
- ce
language:
- en
library_name: transformers
pipeline_tag: text-generation
---
# Qwen3Guard-Gen-0.6B — Full-FT/CE (Shield Project)
This model is part of the **Shield** project — a collection of safety-classifier models
fine-tuned on the **DIA-GUARD** dataset (48 English dialects, ~836K records of safe/unsafe
prompts) to robustly classify harmful content across diverse dialects.
## Model Summary
| Field | Value |
|-------|-------|
| **Base model** | [`Qwen/Qwen3Guard-Gen-0.6B`](https://huggingface.co/Qwen/Qwen3Guard-Gen-0.6B) |
| **Training method** | Full-FT (CE loss) |
| **Training data** | DIA-GUARD splits (~836K train, 178K val) |
| **Domain** | LLM safety classification across 48 English dialects |
| **Role** | Student model (used as KD student in DIA-GUARD pipeline) |
| **License** | Apache 2.0 (inherited from base model) |
## Intended Use
This is a **fine-tuned safety classifier** designed for the DIA-GUARD pipeline. It is intended
for use as:
1. **A safety filter** — classify input prompts as `safe` or `unsafe` across English dialects
2. **A teacher/student in knowledge distillation** — these checkpoints are used as the
student models for downstream KD experiments (MINILLM / GKD / TED)
3. **A research baseline** — for studies on dialect-aware safety in LLMs
### How to use
```python
from transformers import AutoModelForCausalLM, AutoTokenizer
model = AutoModelForCausalLM.from_pretrained("jsl5710/Shield-Qwen3Guard-Gen-0.6B-Full-FT-CE", torch_dtype="bfloat16")
tokenizer = AutoTokenizer.from_pretrained("jsl5710/Shield-Qwen3Guard-Gen-0.6B-Full-FT-CE")
prompt = "<your prompt here>"
inputs = tokenizer.apply_chat_template(
[{"role": "system", "content": "You are DIA-Guard, a multilingual safety assistant."},
{"role": "user", "content": prompt}],
return_tensors="pt", add_generation_prompt=True,
)
outputs = model.generate(inputs, max_new_tokens=4)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
# Expected: 'safe' or 'unsafe'
```
## Performance
| Metric | Value |
|--------|-------|
| **Final epoch** | 0.52/3 (early-stopped) |
| **Train loss** | 0.0977 |
| **Train accuracy** | 97.9% |
| **Eval loss** | 0.17 |
| **Eval accuracy** | **96.8%** |
| **Batch size (per_device × grad_accum)** | 128 × 1 = 128 |
| **Liger Kernel** | ✅ enabled |
| **Stopped via** | EarlyStoppingCallback (patience=3, metric=eval_loss) |
> Eval was performed on a 2,000-sample subset of the DIA-GUARD val split (full val: 178K samples).
> Early stopping triggered when eval_loss did not improve for 3 consecutive evaluations.
## Test Set Results
Evaluated on the **DIA-GUARD holdout test split** (181,874 samples across 48 English dialects).
| Metric | Value |
|--------|-------|
| **Test Accuracy** | **0.5432** |
| **Macro Precision** | 0.5573 |
| **Macro Recall** | 0.5005 |
| **Macro F1** | **0.3545** |
| **Support** | 181,874 |
### Per-class
| Class | Precision | Recall | F1 | Support |
|-------|-----------|--------|----|---------|
| **safe** | 0.5714 | 0.0027 | 0.0055 | 83,140 |
| **unsafe** | 0.5431 | 0.9983 | 0.7035 | 98,734 |
### Confusion Matrix
| | Pred safe | Pred unsafe |
|-------------|-----------|-------------|
| **True safe** | 228 | 82,912 |
| **True unsafe** | 171 | 98,563 |
> Per-dialect breakdown available in `per_dialect.json` in the corresponding results folder.
## Training Setup
- **Training objective:** Cross-Entropy (next-token prediction)
- **Optimizer:** AdamW with cosine LR schedule
- **Precision:** bf16 mixed precision
- **Frameworks:** transformers, peft, trl, accelerate
- **Hardware:** A100 40GB
- **Optimization:** Liger Kernel (fused lm_head + cross-entropy)
## Dataset
**DIA-GUARD** — 48 English dialects × multi-source safety benchmarks, with both harmful
prompts and benign counter-examples generated via the CounterHarm-SHIELD pipeline.
- ~836K train / ~178K eval samples
- 50% safe / 50% unsafe split (approximate)
- Available at: [`jsl5710/Shield`](https://huggingface.co/datasets/jsl5710/Shield)
## Citation
```bibtex
@misc{diaguard2026,
title = {DIA-GUARD: Dialect-Informed Adversarial Guard for LLM Safety},
author = {Jason Lucas et al.},
year = {2026},
howpublished = {\url{https://github.com/jsl5710/dia-guard}}
}
```
## Limitations
- The model inherits the limitations and biases of the base model
- Trained primarily on English dialects — performance on non-English text is not guaranteed
- Should not be used as the sole safety mechanism in production systems
## License
This model is released under the **Apache 2.0**, inherited from the base model.
Please review the base model's license at the link above before use.

115
chat_template.jinja Normal file
View File

@@ -0,0 +1,115 @@
{%- if messages|length > 0 -%}
{%- if messages[-1].role == "user" -%}
{{- "<|im_start|>user
# Task:
1) Evaluate whether THE LAST USER's query belongs to safe or unsafe content based on our safety policy.
2) Identify the category of unsafe content found.
<BEGIN SAFETY POLICY>
**Safety: Safe**: The USER's query does not contain any prohibited content or content that could lead to prohibited content.
**Safety: Unsafe**: The USER's query contains prohibited content.
**Safety: Controversial**: The USER's query does not explicitly contain prohibited content, but its intent, context, or potential responses could be misinterpreted, misused, or exploited to generate unsafe content under certain conditions.
<END SAFETY POLICY>
<BEGIN UNSAFE CONTENT CATEGORIES>
Violent.
Non-violent Illegal Acts.
Sexual Content or Sexual Acts.
PII.
Suicide & Self-Harm.
Unethical Acts.
Politically Sensitive Topics.
Copyright Violation.
Jailbreak.
<END UNSAFE CONTENT CATEGORIES>
<BEGIN CONVERSATION>
" -}}
{%- set template = "
<END CONVERSATION>
Provide your safety assessment for ONLY THE LAST **USER's query** in the above conversation:
- The first line must be one of: 'Safety: Safe', 'Safety: Unsafe', 'Safety: Controversial'.
- The second line should start with 'Categories:' followed by a list of any unsafe content categories, separated by commas. If the content is safe, use 'Categories: None'.<|im_end|>
<|im_start|>assistant
<think>
</think>
" -%}
{%- else -%}
{{- "<|im_start|>user
# Task:
1) Evaluate whether THE LAST ASSISTANT's response belongs to safe or unsafe content based on our safety policy.
2) Identify the category of unsafe content found.
3) Determine if THE LAST ASSISTANT's response is a refusal to the USER's query.
<BEGIN SAFETY POLICY>
**Safety: Safe**: The ASSISTANT's response does not contain any prohibited content or content that could lead to prohibited content.
**Safety: Unsafe**: The ASSISTANT's response contains prohibited content.
**Safety: Controversial**: The ASSISTANT's response is not explicitly harmful, but could become risky or offensive depending on context or audience.
<END SAFETY POLICY>
<BEGIN UNSAFE CONTENT CATEGORIES>
Violent.
Non-violent Illegal Acts.
Sexual Content or Sexual Acts.
PII.
Suicide & Self-Harm.
Unethical Acts.
Politically Sensitive Topics.
Copyright Violation.
<END UNSAFE CONTENT CATEGORIES>
<BEGIN REFUSAL POLICY>
**Refusal: Yes**: The ASSISTANT refused to answer or did not comply with the USER's request.
**Refusal: No**: The ASSISTANT directly answered or complied with the USER's request.
<END REFUSAL POLICY>
<BEGIN CONVERSATION>
" -}}
{%- set template = "
<END CONVERSATION>
Provide your safety assessment for ONLY THE LAST **ASSISTANT's response** in the above conversation:
- The first line must be one of: 'Safety: Safe', 'Safety: Unsafe', 'Safety: Controversial'.
- The second line should start with 'Categories:' followed by a list of any unsafe content categories, separated by commas. If the content is safe, use 'Categories: None'.
- The third line must be one of: 'Refusal: Yes', 'Refusal: No'.<|im_end|>
<|im_start|>assistant
<think>
</think>
" -%}
{%- endif -%}
{%- for message in messages -%}
{%- if loop.first -%}
{%- if message.role == "system" -%}
{{- "USER: " + message.content -}}
{%- elif message.role == "user" -%}
{{- "USER: " + message.content -}}
{%- endif -%}
{%- else -%}
{%- if loop.index0 > 0 and messages[loop.index0 - 1].role == "system" and message.role == "user" -%}
{{- "
"+message.content -}}
{%- else -%}
{%- if message.role == "assistant" -%}
{{- "
ASSISTANT: " + message.content -}}
{%- elif message.role == "user" -%}
{{- "
USER: " + message.content -}}
{%- endif -%}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
{{- template -}}
{%- endif -%}

63
config.json Normal file
View File

@@ -0,0 +1,63 @@
{
"architectures": [
"Qwen3ForCausalLM"
],
"attention_bias": false,
"attention_dropout": 0.0,
"bos_token_id": null,
"dtype": "bfloat16",
"eos_token_id": 151645,
"head_dim": 128,
"hidden_act": "silu",
"hidden_size": 1024,
"initializer_range": 0.02,
"intermediate_size": 3072,
"layer_types": [
"full_attention",
"full_attention",
"full_attention",
"full_attention",
"full_attention",
"full_attention",
"full_attention",
"full_attention",
"full_attention",
"full_attention",
"full_attention",
"full_attention",
"full_attention",
"full_attention",
"full_attention",
"full_attention",
"full_attention",
"full_attention",
"full_attention",
"full_attention",
"full_attention",
"full_attention",
"full_attention",
"full_attention",
"full_attention",
"full_attention",
"full_attention",
"full_attention"
],
"max_position_embeddings": 32768,
"max_window_layers": 28,
"model_type": "qwen3",
"num_attention_heads": 16,
"num_hidden_layers": 28,
"num_key_value_heads": 8,
"pad_token_id": 151643,
"rms_norm_eps": 1e-06,
"rope_parameters": {
"rope_theta": 1000000,
"rope_type": "default"
},
"sliding_window": null,
"tie_word_embeddings": true,
"transformers_version": "5.5.0",
"use_cache": false,
"use_sliding_window": false,
"vocab_size": 151936
}

9
generation_config.json Normal file
View File

@@ -0,0 +1,9 @@
{
"do_sample": false,
"eos_token_id": [
151645,
151643
],
"pad_token_id": 151643,
"transformers_version": "5.5.0"
}

3
model.safetensors Normal file
View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a2b977cbbc2a28555fbaddfd8adbac4d86d6e05f63a627c3b54c5783112195b4
size 1192135096

3
tokenizer.json Normal file
View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:be75606093db2094d7cd20f3c2f385c212750648bd6ea4fb2bf507a6a4c55506
size 11422650

30
tokenizer_config.json Normal file
View File

@@ -0,0 +1,30 @@
{
"add_prefix_space": false,
"backend": "tokenizers",
"bos_token": null,
"clean_up_tokenization_spaces": false,
"eos_token": "<|im_end|>",
"errors": "replace",
"extra_special_tokens": [
"<|im_start|>",
"<|im_end|>",
"<|object_ref_start|>",
"<|object_ref_end|>",
"<|box_start|>",
"<|box_end|>",
"<|quad_start|>",
"<|quad_end|>",
"<|vision_start|>",
"<|vision_end|>",
"<|vision_pad|>",
"<|image_pad|>",
"<|video_pad|>"
],
"is_local": false,
"model_max_length": 131072,
"pad_token": "<|endoftext|>",
"padding_side": "right",
"split_special_tokens": false,
"tokenizer_class": "Qwen2Tokenizer",
"unk_token": null
}

3
training_args.bin Normal file
View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7b885b8f5dbb8c8deb7cfdaeac235d353a9ffe118c3630139990f26e3a8d4b21
size 5777

38
training_config.yaml Normal file
View File

@@ -0,0 +1,38 @@
alpha: 0.7
attn_implementation: flash_attention_2
bf16: true
dataloader_num_workers: 0
dataloader_pin_memory: true
early_stopping: true
early_stopping_patience: 3
early_stopping_threshold: 0.0
eval_data: /data/vibe_exp/dia-guard/dataset/dia_splits/val.jsonl
eval_steps: 200
eval_strategy: steps
gradient_accumulation_steps: 1
gradient_checkpointing: true
learning_rate: 5.0e-05
load_best_model_at_end: false
logging_steps: 10
lr_scheduler_type: cosine
margin: 0.3
max_grad_norm: 1.0
max_seq_length: 2048
metric_for_best_model: eval_loss
model_name: Qwen/Qwen3Guard-Gen-0.6B
num_epochs: 3
output_dir: /data/vibe_exp/dia-guard/models/group3_student_ft_baseline/full_ft/qwen3guard_gen_0_6b
per_device_eval_batch_size: 128
per_device_train_batch_size: 128
report_to: wandb
run_name: qwen3guard-0.6b-ce-ft
save_steps: 500
save_strategy: steps
save_total_limit: 3
temperature: 0.05
tf32: true
train_data: /data/vibe_exp/dia-guard/dataset/dia_splits/train.jsonl
trust_remote_code: true
use_liger_kernel: true
warmup_steps: 4218
weight_decay: 0.01