初始化项目,由ModelHub XC社区提供模型
Model: npanium/deepseek-r1-qwen7b-smartcontract-grpo Source: Original Platform
This commit is contained in:
36
.gitattributes
vendored
Normal file
36
.gitattributes
vendored
Normal 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
|
||||||
192
README.md
Normal file
192
README.md
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
---
|
||||||
|
library_name: transformers
|
||||||
|
base_model: deepseek-ai/DeepSeek-R1-Distill-Qwen-7B
|
||||||
|
tags:
|
||||||
|
- smart-contracts
|
||||||
|
- solidity
|
||||||
|
- security
|
||||||
|
- vulnerability-detection
|
||||||
|
- grpo
|
||||||
|
- lora
|
||||||
|
- reinforcement-learning
|
||||||
|
language:
|
||||||
|
- en
|
||||||
|
license: mit
|
||||||
|
---
|
||||||
|
|
||||||
|
# DeepSeek-R1-Distill-Qwen-7B — Smart Contract Vulnerability Detection
|
||||||
|
|
||||||
|
RL fine-tuned version of DeepSeek-R1-Distill-Qwen-7B for detecting vulnerabilities in Solidity smart contracts. Fine-tuned using GRPO (Group Relative Policy Optimization) with LoRA on the CGT (Consolidated Ground Truth) dataset.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Model Description
|
||||||
|
|
||||||
|
- **Base model:** deepseek-ai/DeepSeek-R1-Distill-Qwen-7B
|
||||||
|
- **Fine-tuning method:** GRPO + LoRA
|
||||||
|
- **Task:** Smart contract vulnerability detection and classification
|
||||||
|
- **Developer:** Nishant Pandav ([@npanium](https://github.com/npanium))
|
||||||
|
- **Repository:** [https://github.com/npanium/smartcontracts-vulnerability-r1](https://github.com/npanium/smartcontracts-vulnerability-r1)
|
||||||
|
- **License:** MIT
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## What it does
|
||||||
|
|
||||||
|
Given a Solidity smart contract, the model:
|
||||||
|
1. Reasons through the code using chain-of-thought inside `<think>` tags
|
||||||
|
2. Determines whether the contract is vulnerable
|
||||||
|
3. Classifies the vulnerability by DASP category (1–9) and SWC ID (100–136)
|
||||||
|
|
||||||
|
Output format:
|
||||||
|
```
|
||||||
|
<think>
|
||||||
|
... reasoning about the contract ...
|
||||||
|
</think>
|
||||||
|
VULNERABLE: yes/no
|
||||||
|
DASP_CATEGORY: N
|
||||||
|
SWC_ID: NNN
|
||||||
|
EXPLANATION: ...
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Results
|
||||||
|
|
||||||
|
Evaluated on 1,478 held-out contracts from the CGT dataset:
|
||||||
|
|
||||||
|
| Metric | Before (base) | After (fine-tuned) | Delta |
|
||||||
|
|--------|--------------|-------------------|-------|
|
||||||
|
| Detection accuracy (Tier 1) | 23.0% | 74.3% | **+51.3%** |
|
||||||
|
| DASP category (Tier 2) | 8.8% | 11.3% | +2.5% |
|
||||||
|
| SWC ID (Tier 3) | 3.0% | 0.0% | -3.0% |
|
||||||
|
| Overall | 11.6% | 28.5% | **+16.9%** |
|
||||||
|
| Parse failure rate | 40.2% | 0.0% | **-40.2%** |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## How to Use
|
||||||
|
|
||||||
|
```python
|
||||||
|
from transformers import AutoModelForCausalLM, AutoTokenizer
|
||||||
|
import torch
|
||||||
|
|
||||||
|
model_id = "npanium/deepseek-r1-qwen7b-smartcontract-grpo"
|
||||||
|
|
||||||
|
tokenizer = AutoTokenizer.from_pretrained(model_id)
|
||||||
|
model = AutoModelForCausalLM.from_pretrained(
|
||||||
|
model_id,
|
||||||
|
torch_dtype=torch.bfloat16,
|
||||||
|
device_map="auto",
|
||||||
|
)
|
||||||
|
|
||||||
|
contract = """
|
||||||
|
pragma solidity ^0.4.18;
|
||||||
|
contract Vulnerable {
|
||||||
|
mapping(address => uint) public balances;
|
||||||
|
|
||||||
|
function withdraw(uint _amount) public {
|
||||||
|
if (balances[msg.sender] >= _amount) {
|
||||||
|
msg.sender.call.value(_amount)();
|
||||||
|
balances[msg.sender] -= _amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
prompt = f"""Analyze this Solidity smart contract for security vulnerabilities.
|
||||||
|
Think step by step inside <think> tags, then provide your assessment.
|
||||||
|
|
||||||
|
``solidity
|
||||||
|
{contract}``
|
||||||
|
|
||||||
|
|
||||||
|
Use this exact format:
|
||||||
|
VULNERABLE: yes/no
|
||||||
|
DASP_CATEGORY: [1-9]
|
||||||
|
SWC_ID: [100-136]
|
||||||
|
EXPLANATION: [one sentence]"""
|
||||||
|
|
||||||
|
messages = [{"role": "user", "content": prompt}]
|
||||||
|
inputs = tokenizer.apply_chat_template(
|
||||||
|
messages,
|
||||||
|
return_tensors="pt",
|
||||||
|
add_generation_prompt=True,
|
||||||
|
)
|
||||||
|
if hasattr(inputs, "input_ids"):
|
||||||
|
inputs = inputs.input_ids
|
||||||
|
inputs = inputs.to(model.device)
|
||||||
|
|
||||||
|
with torch.no_grad():
|
||||||
|
outputs = model.generate(
|
||||||
|
inputs,
|
||||||
|
max_new_tokens=1024,
|
||||||
|
temperature=0.1,
|
||||||
|
do_sample=True,
|
||||||
|
pad_token_id=tokenizer.eos_token_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = tokenizer.decode(
|
||||||
|
outputs[0][inputs.shape[1]:],
|
||||||
|
skip_special_tokens=True,
|
||||||
|
)
|
||||||
|
print(response)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Training Details
|
||||||
|
|
||||||
|
### Dataset
|
||||||
|
|
||||||
|
**CGT (Consolidated Ground Truth)** — [github.com/gsalzer/cgt](https://github.com/gsalzer/cgt)
|
||||||
|
|
||||||
|
Consolidates 13 prior smart contract vulnerability datasets. Labels cross-validated across source datasets.
|
||||||
|
|
||||||
|
| Split | Examples |
|
||||||
|
|-------|----------|
|
||||||
|
| Train | 5,910 |
|
||||||
|
| Test (locked) | 1,478 |
|
||||||
|
|
||||||
|
### Training Hyperparameters
|
||||||
|
|
||||||
|
| Parameter | Value |
|
||||||
|
|-----------|-------|
|
||||||
|
| Training regime | bf16 mixed precision |
|
||||||
|
| Learning rate | 5e-6 |
|
||||||
|
| LoRA rank | 16 |
|
||||||
|
| LoRA alpha | 32 |
|
||||||
|
| LoRA target modules | q_proj, v_proj, k_proj, o_proj |
|
||||||
|
| Generations per prompt | 8 |
|
||||||
|
| Max completion length | 1024 |
|
||||||
|
| Gradient accumulation steps | 8 |
|
||||||
|
| Epochs | 1 |
|
||||||
|
|
||||||
|
### Hardware
|
||||||
|
|
||||||
|
- **GPU:** NVIDIA A100 SXM4 80GB
|
||||||
|
- **Cloud provider:** Fluence Network
|
||||||
|
- **Training duration:** ~48 hours
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Limitations
|
||||||
|
|
||||||
|
**Outcome reward only.** The reward function validates whether the final label is correct, not whether the reasoning is valid. The model may produce plausible-sounding analysis that doesn't actually justify the conclusion.
|
||||||
|
|
||||||
|
**SWC ID regression.** Post-training SWC ID accuracy dropped to zero. The model prioritised the higher-weighted binary detection reward at the expense of fine-grained weakness classification.
|
||||||
|
|
||||||
|
**Context window.** Contracts exceeding ~4,000 characters were excluded from training. Performance on very large contracts is untested.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Citation
|
||||||
|
|
||||||
|
```bibtex
|
||||||
|
@misc{pandav2026scvulnrl,
|
||||||
|
author = {Pandav, Nishant},
|
||||||
|
title = {Smart Contract Vulnerability Detection via RL Fine-Tuning},
|
||||||
|
year = {2026},
|
||||||
|
url = {https://github.com/npanium/smartcontracts-vulnerability-r1}
|
||||||
|
}
|
||||||
|
```
|
||||||
1
chat_template.jinja
Normal file
1
chat_template.jinja
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{% if not add_generation_prompt is defined %}{% set add_generation_prompt = false %}{% endif %}{% set ns = namespace(is_first=false, is_tool=false, is_output_first=true, system_prompt='') %}{%- for message in messages %}{%- if message['role'] == 'system' %}{% set ns.system_prompt = message['content'] %}{%- endif %}{%- endfor %}{{bos_token}}{{ns.system_prompt}}{%- for message in messages %}{%- if message['role'] == 'user' %}{%- set ns.is_tool = false -%}{{'<|User|>' + message['content']}}{%- endif %}{%- if message['role'] == 'assistant' and message['content'] is none %}{%- set ns.is_tool = false -%}{%- for tool in message['tool_calls']%}{%- if not ns.is_first %}{{'<|Assistant|><|tool▁calls▁begin|><|tool▁call▁begin|>' + tool['type'] + '<|tool▁sep|>' + tool['function']['name'] + '\n' + '```json' + '\n' + tool['function']['arguments'] + '\n' + '```' + '<|tool▁call▁end|>'}}{%- set ns.is_first = true -%}{%- else %}{{'\n' + '<|tool▁call▁begin|>' + tool['type'] + '<|tool▁sep|>' + tool['function']['name'] + '\n' + '```json' + '\n' + tool['function']['arguments'] + '\n' + '```' + '<|tool▁call▁end|>'}}{{'<|tool▁calls▁end|><|end▁of▁sentence|>'}}{%- endif %}{%- endfor %}{%- endif %}{%- if message['role'] == 'assistant' and message['content'] is not none %}{%- if ns.is_tool %}{{'<|tool▁outputs▁end|>' + message['content'] + '<|end▁of▁sentence|>'}}{%- set ns.is_tool = false -%}{%- else %}{% set content = message['content'] %}{% if '</think>' in content %}{% set content = content.split('</think>')[-1] %}{% endif %}{{'<|Assistant|>' + content + '<|end▁of▁sentence|>'}}{%- endif %}{%- endif %}{%- if message['role'] == 'tool' %}{%- set ns.is_tool = true -%}{%- if ns.is_output_first %}{{'<|tool▁outputs▁begin|><|tool▁output▁begin|>' + message['content'] + '<|tool▁output▁end|>'}}{%- set ns.is_output_first = false %}{%- else %}{{'\n<|tool▁output▁begin|>' + message['content'] + '<|tool▁output▁end|>'}}{%- endif %}{%- endif %}{%- endfor -%}{% if ns.is_tool %}{{'<|tool▁outputs▁end|>'}}{% endif %}{% if add_generation_prompt and not ns.is_tool %}{{'<|Assistant|><think>\n'}}{% endif %}
|
||||||
62
config.json
Normal file
62
config.json
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
{
|
||||||
|
"architectures": [
|
||||||
|
"Qwen2ForCausalLM"
|
||||||
|
],
|
||||||
|
"attention_dropout": 0.0,
|
||||||
|
"bos_token_id": 151643,
|
||||||
|
"dtype": "bfloat16",
|
||||||
|
"eos_token_id": 151643,
|
||||||
|
"hidden_act": "silu",
|
||||||
|
"hidden_size": 3584,
|
||||||
|
"initializer_range": 0.02,
|
||||||
|
"intermediate_size": 18944,
|
||||||
|
"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": 131072,
|
||||||
|
"max_window_layers": 28,
|
||||||
|
"model_type": "qwen2",
|
||||||
|
"num_attention_heads": 28,
|
||||||
|
"num_hidden_layers": 28,
|
||||||
|
"num_key_value_heads": 4,
|
||||||
|
"pad_token_id": null,
|
||||||
|
"rms_norm_eps": 1e-06,
|
||||||
|
"rope_parameters": {
|
||||||
|
"rope_theta": 10000,
|
||||||
|
"rope_type": "default"
|
||||||
|
},
|
||||||
|
"sliding_window": null,
|
||||||
|
"tie_word_embeddings": false,
|
||||||
|
"transformers_version": "5.3.0",
|
||||||
|
"use_cache": true,
|
||||||
|
"use_mrope": false,
|
||||||
|
"use_sliding_window": false,
|
||||||
|
"vocab_size": 152064
|
||||||
|
}
|
||||||
9
generation_config.json
Normal file
9
generation_config.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"_from_model_config": true,
|
||||||
|
"bos_token_id": 151646,
|
||||||
|
"do_sample": true,
|
||||||
|
"eos_token_id": 151643,
|
||||||
|
"temperature": 0.6,
|
||||||
|
"top_p": 0.95,
|
||||||
|
"transformers_version": "5.3.0"
|
||||||
|
}
|
||||||
3
model.safetensors
Normal file
3
model.safetensors
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:f870ae6b1169e03774feb6ec0d28fa34980f35f573e34ce18905b7f473a1cfb9
|
||||||
|
size 15231272152
|
||||||
3
tokenizer.json
Normal file
3
tokenizer.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:322664cdc3082b6eba003af5228a77ca1d7936d402e584ecde8f15d3d98bdb72
|
||||||
|
size 11421911
|
||||||
13
tokenizer_config.json
Normal file
13
tokenizer_config.json
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"backend": "tokenizers",
|
||||||
|
"bos_token": "<|begin▁of▁sentence|>",
|
||||||
|
"clean_up_tokenization_spaces": false,
|
||||||
|
"eos_token": "<|end▁of▁sentence|>",
|
||||||
|
"is_local": false,
|
||||||
|
"legacy": true,
|
||||||
|
"model_max_length": 16384,
|
||||||
|
"pad_token": "<|end▁of▁sentence|>",
|
||||||
|
"sp_model_kwargs": {},
|
||||||
|
"tokenizer_class": "TokenizersBackend",
|
||||||
|
"unk_token": null
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user