docs: document code agent and neutralize identity

pull/808/head
RileyChen23 2026-07-12 17:56:29 +08:00
parent 65def67cee
commit 4ec1b84d96
4 changed files with 136 additions and 59 deletions

View File

@ -1,28 +1,7 @@
<div align="center"> <div align="center">
<h1>Lightweight LLM & Code Agent Lab</h1>
![logo](./images/logo.png) <p>基于 MiniMind 的轻量模型训练、代码生成与执行反馈实验</p>
<p><a href="./LICENSE">Apache-2.0 License</a></p>
</div>
<div align="center">
![visitors](https://visitor-badge.laobi.icu/badge?page_id=jingyaogong/minimind)
[![GitHub Repo stars](https://img.shields.io/github/stars/jingyaogong/minimind?style=social)](https://github.com/jingyaogong/minimind/stargazers)
[![GitHub Code License](https://img.shields.io/github/license/jingyaogong/minimind)](LICENSE)
[![GitHub last commit](https://img.shields.io/github/last-commit/jingyaogong/minimind)](https://github.com/jingyaogong/minimind/commits/master)
[![GitHub pull request](https://img.shields.io/badge/PRs-welcome-blue)](https://github.com/jingyaogong/minimind/pulls)
[![Collection](https://img.shields.io/badge/🤗-MiniMind%20%20Collection-blue)](https://huggingface.co/collections/jingyaogong/minimind-66caf8d999f5c7fa64f399e5)
</div>
<div align="center">
![GitHub Trend](https://trendshift.io/api/badge/repositories/12586)
</div>
<div align="center">
<h3>"大道至简"</h3>
</div> </div>
<div align="center"> <div align="center">
@ -31,6 +10,8 @@
</div> </div>
> 本仓库基于开源项目 [jingyaogong/minimind](https://github.com/jingyaogong/minimind) 进行复现与二次开发,保留原许可证、模型兼容性和上游致谢。新增的代码生成 Agent 支持代码提取、受控执行、隐藏测试反馈、pass@k 评估,以及面向 GRPO/CISPO 的可验证奖励。详见 [代码生成 Agent 文档](./docs/code-agent.md)。
* 此开源项目旨在完全从 0 开始,仅用 3 块钱成本与 2 小时训练时间,即可训练出规模约为 64M 的超小语言模型 MiniMind。 * 此开源项目旨在完全从 0 开始,仅用 3 块钱成本与 2 小时训练时间,即可训练出规模约为 64M 的超小语言模型 MiniMind。
* MiniMind 系列极其轻量,主线最小版本体积约为 GPT-3 的 $\frac{1}{2700}$,力求让普通个人 GPU 也能快速完成训练与复现。 * MiniMind 系列极其轻量,主线最小版本体积约为 GPT-3 的 $\frac{1}{2700}$,力求让普通个人 GPU 也能快速完成训练与复现。
* 项目同时开源了大模型的极简结构与完整训练链路,覆盖 MoE、数据清洗、预训练(Pretrain)、监督微调(SFT)、LoRA、RLHF(DPO)、RLAIF(PPO / GRPO / CISPO)、Tool Use、Agentic RL、自适应思考与模型蒸馏等全过程代码。 * 项目同时开源了大模型的极简结构与完整训练链路,覆盖 MoE、数据清洗、预训练(Pretrain)、监督微调(SFT)、LoRA、RLHF(DPO)、RLAIF(PPO / GRPO / CISPO)、Tool Use、Agentic RL、自适应思考与模型蒸馏等全过程代码。
@ -786,8 +767,8 @@ LoRA 很适合处理“如何在尽量保留通用能力的前提下,让模型
例2:自我认知数据 例2:自我认知数据
```jsonl ```jsonl
{"conversations": [{"role": "user", "content": "你叫什么名字?"}, {"role": "assistant", "content": "您好,我名叫 MiniMind,是由 Jingyao Gong 开发的人工智能助手。我可以帮助你解决各种问题,包括翻译、推荐内容等等。"}]} {"conversations": [{"role": "user", "content": "你叫什么名字?"}, {"role": "assistant", "content": "您好,我是一个开源的轻量级人工智能助手,可以帮助完成问答、翻译和内容整理等任务。"}]}
{"conversations": [{"role": "user", "content": "你是谁"}, {"role": "assistant", "content": "您好,我是 MiniMind,由 Jingyao Gong 创建。我的主要职责是提供准确的回答和帮助。"}]} {"conversations": [{"role": "user", "content": "你是谁"}, {"role": "assistant", "content": "您好,我是一个用于语言模型实验的开源助手,主要职责是提供准确的回答和帮助。"}]}
``` ```
此时可将【基模 + LoRA 权重】组合使用,从而在保留基础模型通用能力的同时,增强特定领域表现。训练完成后也可以通过 `eval_llm.py` 做简单测试。 此时可将【基模 + LoRA 权重】组合使用,从而在保留基础模型通用能力的同时,增强特定领域表现。训练完成后也可以通过 `eval_llm.py` 做简单测试。
@ -802,7 +783,7 @@ python eval_llm.py --weight full_sft --lora_weight lora_medical
python eval_llm.py --weight full_sft --lora_weight lora_identity python eval_llm.py --weight full_sft --lora_weight lora_identity
👶: 你和openai是什么关系? 👶: 你和openai是什么关系?
🤖️: 我是 MiniMind,一个由 Jingyao Gong 开发的人工智能助手。我通过自然语言处理和算法训练来与用户进行交互。 🤖️: 我是一个开源的轻量级人工智能助手,通过自然语言处理模型与用户进行交互。
``` ```
PS:如果有更充足的数据,也可以直接做 `full_sft` 全参微调;不过这通常需要更谨慎地混合通用数据与领域数据,否则很容易因为过拟合垂域样本而损失模型原有的通用性。 PS:如果有更充足的数据,也可以直接做 `full_sft` 全参微调;不过这通常需要更谨慎地混合通用数据与领域数据,否则很容易因为过拟合垂域样本而损失模型原有的通用性。

View File

@ -1,28 +1,7 @@
<div align="center"> <div align="center">
<h1>Lightweight LLM & Code Agent Lab</h1>
![logo](./images/logo.png) <p>Lightweight model training, code generation, and execution-feedback experiments built on MiniMind</p>
<p><a href="./LICENSE">Apache-2.0 License</a></p>
</div>
<div align="center">
![visitors](https://visitor-badge.laobi.icu/badge?page_id=jingyaogong/minimind)
[![GitHub Repo stars](https://img.shields.io/github/stars/jingyaogong/minimind?style=social)](https://github.com/jingyaogong/minimind/stargazers)
[![GitHub Code License](https://img.shields.io/github/license/jingyaogong/minimind)](LICENSE)
[![GitHub last commit](https://img.shields.io/github/last-commit/jingyaogong/minimind)](https://github.com/jingyaogong/minimind/commits/master)
[![GitHub pull request](https://img.shields.io/badge/PRs-welcome-blue)](https://github.com/jingyaogong/minimind/pulls)
[![Collection](https://img.shields.io/badge/🤗-MiniMind%20%20Collection-blue)](https://huggingface.co/collections/jingyaogong/minimind-66caf8d999f5c7fa64f399e5)
</div>
<div align="center">
![GitHub Trend](https://trendshift.io/api/badge/repositories/12586)
</div>
<div align="center">
<h3>"The Great Way is Simple"</h3>
</div> </div>
<div align="center"> <div align="center">
@ -31,6 +10,8 @@
</div> </div>
> This repository reproduces and extends the open-source [jingyaogong/minimind](https://github.com/jingyaogong/minimind) project while preserving its license, model compatibility, and upstream attribution. The added code-generation agent provides code extraction, controlled execution, hidden-test feedback, pass@k evaluation, and verifiable rewards for GRPO/CISPO. See the [code agent documentation](./docs/code-agent.md).
* This open-source project aims to train MiniMind, an ultra-small language model with about 64M parameters, entirely from scratch with only about RMB 3 in cost and 2 hours of training time. * This open-source project aims to train MiniMind, an ultra-small language model with about 64M parameters, entirely from scratch with only about RMB 3 in cost and 2 hours of training time.
* The MiniMind series is intentionally lightweight. The smallest model on the main branch is about $\frac{1}{2700}$ the size of GPT-3, making full training and reproduction feasible even on ordinary personal GPUs. * The MiniMind series is intentionally lightweight. The smallest model on the main branch is about $\frac{1}{2700}$ the size of GPT-3, making full training and reproduction feasible even on ordinary personal GPUs.
* The project provides a minimalist model architecture and an end-to-end LLM training pipeline, covering MoE, data cleaning, pretraining, Supervised Fine-Tuning (SFT), LoRA, RLHF (DPO), RLAIF (PPO / GRPO / CISPO), Tool Use, Agentic RL, Adaptive Thinking, and Model Distillation. * The project provides a minimalist model architecture and an end-to-end LLM training pipeline, covering MoE, data cleaning, pretraining, Supervised Fine-Tuning (SFT), LoRA, RLHF (DPO), RLAIF (PPO / GRPO / CISPO), Tool Use, Agentic RL, Adaptive Thinking, and Model Distillation.
@ -786,8 +767,8 @@ Example 1: Vertical domain data
Example 2: Self-awareness data Example 2: Self-awareness data
```jsonl ```jsonl
{"conversations": [{"role": "user", "content": "你叫什么名字?"}, {"role": "assistant", "content": "您好,我名叫 MiniMind,是由 Jingyao Gong 开发的人工智能助手。我可以帮助你解决各种问题,包括翻译、推荐内容等等。"}]} {"conversations": [{"role": "user", "content": "你叫什么名字?"}, {"role": "assistant", "content": "您好,我是一个开源的轻量级人工智能助手,可以帮助完成问答、翻译和内容整理等任务。"}]}
{"conversations": [{"role": "user", "content": "你是谁"}, {"role": "assistant", "content": "您好,我是 MiniMind,由 Jingyao Gong 创建。我的主要职责是提供准确的回答和帮助。"}]} {"conversations": [{"role": "user", "content": "你是谁"}, {"role": "assistant", "content": "您好,我是一个用于语言模型实验的开源助手,主要职责是提供准确的回答和帮助。"}]}
``` ```
At this point, the [base model + LoRA weights] can be used in combination, preserving the base model's general capabilities while enhancing specific domain performance. After training, simple tests can also be done via `eval_llm.py`. At this point, the [base model + LoRA weights] can be used in combination, preserving the base model's general capabilities while enhancing specific domain performance. After training, simple tests can also be done via `eval_llm.py`.
@ -802,7 +783,7 @@ python eval_llm.py --weight full_sft --lora_weight lora_medical
python eval_llm.py --weight full_sft --lora_weight lora_identity python eval_llm.py --weight full_sft --lora_weight lora_identity
👶: 你和openai是什么关系? 👶: 你和openai是什么关系?
🤖️: 我是 MiniMind,一个由 Jingyao Gong 开发的人工智能助手。我通过自然语言处理和算法训练来与用户进行交互。 🤖️: 我是一个开源的轻量级人工智能助手,通过自然语言处理模型与用户进行交互。
``` ```
PS: If you have sufficient data, you can also perform `full_sft` full-parameter fine-tuning directly. This usually requires careful mixing of general and domain-specific data; otherwise, the model may lose part of its general capability due to overfitting on vertical-domain samples. PS: If you have sufficient data, you can also perform `full_sft` full-parameter fine-tuning directly. This usually requires careful mixing of general and domain-specific data; otherwise, the model may lose part of its general capability due to overfitting on vertical-domain samples.

118
docs/code-agent.md Normal file
View File

@ -0,0 +1,118 @@
# Code Generation Agent
This extension adds an execution-feedback loop for Python algorithm generation while keeping the original MiniMind model and checkpoint format unchanged.
## Architecture
```mermaid
flowchart LR
A[Algorithm task] --> B[MiniMind or OpenAI-compatible model]
B --> C[Python code extraction]
C --> D[AST policy validation]
D --> E[Isolated subprocess]
E --> F[Deterministic tests]
F --> G[Structured feedback]
G -->|repair prompt| B
F --> H[Verifiable reward]
H --> I[GRPO or CISPO]
F --> J[pass@k and error metrics]
```
The implementation is split into small, testable modules:
- `code_agent/verifier.py`: code extraction, AST policy checks, subprocess execution, timeout and structured results.
- `code_agent/reward.py`: transparent reward components and grouped GRPO scoring.
- `code_agent/agent.py`: generate-execute-feedback-repair loop with hidden-test-safe feedback.
- `code_agent/evaluation.py`: compile rate, execution rate, test pass rate, error counts and unbiased pass@k.
- `code_agent/dataset.py`: JSONL code tasks adapted to the MiniMind chat template.
- `code_agent/backends.py`: OpenAI-compatible inference adapter for MiniMind, vLLM and SGLang.
## Task format
Each JSONL record contains a prompt, a required function name, and JSON-serializable tests:
```json
{"task_id":"add-two","prompt":"Implement add(a, b).","entry_point":"add","tests":[{"args":[1,2],"expected":3}]}
```
`dataset/code_rl_mini.jsonl` contains four smoke-test tasks. It is deliberately too small for a meaningful training claim; use it to validate the pipeline before preparing a larger train/validation/test split.
## Evaluate saved candidates
```bash
python scripts/eval_codegen.py \
--tasks dataset/code_rl_mini.jsonl \
--predictions tests/fixtures/code_rl_predictions.jsonl \
--ks 1 2
```
The report separates:
- `compile_rate`: candidate passed syntax and policy validation;
- `execution_rate`: candidate completed without a timeout or runtime exception;
- `test_pass_rate`: fraction of deterministic tests passed;
- `pass@k`: probability that at least one of `k` sampled candidates is correct;
- `status_counts`: syntax, policy, timeout, runtime and wrong-answer failure modes.
## Run the repair agent
Start the repository's OpenAI-compatible service, then run:
```bash
python scripts/run_code_agent.py \
--tasks dataset/code_rl_mini.jsonl \
--base-url http://localhost:8998/v1 \
--model minimind \
--max-attempts 3
```
Hidden-test details are not sent back to the model by default. Add `--reveal-test-details` only for public development tests.
## Train with verifiable rewards
From the repository root:
```bash
cd trainer
python train_grpo.py \
--reward_type code \
--data_path ../dataset/code_rl_mini.jsonl \
--num_generations 6 \
--loss_type grpo \
--from_weight full_sft
```
The training log includes `degenerate_group_rate`. A group whose candidates all receive the same reward has zero normalized advantage and contributes no useful policy-gradient signal. This metric makes the failure mode visible before introducing strategies such as dynamic sampling or harder tasks.
## Reward design
The default reward is intentionally transparent and bounded to `[-1, 1]`:
| Outcome | Reward |
|---|---:|
| all tests passed | 1.0 |
| wrong answer | partial credit from test pass rate |
| runtime error | -0.4 |
| timeout | -0.6 |
| syntax error | -0.8 |
| missing code or policy violation | -1.0 |
Keep hidden tests separate from the prompts and report reward distributions by task difficulty. Otherwise the system can overfit public tests or produce groups with all-identical rewards.
## Safety boundary
The local verifier uses AST checks, a temporary working directory, an isolated Python process, a timeout, and POSIX resource limits. These are defense-in-depth measures, not a secure sandbox. Run hostile or externally submitted code inside a dedicated container or micro-VM with network disabled, a read-only filesystem, strict CPU/memory/process limits, and disposable credentials.
## Experimental protocol
Use the same held-out tasks and sampling parameters for three comparisons:
1. single-pass generation baseline;
2. inference-time execution feedback and repair;
3. execution-reward GRPO/CISPO followed by the same inference procedure.
Record pass@1, pass@k, test pass rate, compile rate, timeout rate, average attempts, average generation length, reward mean/std, KL to the reference model, and degenerate-group rate. Model results should only be added to the resume after this protocol has been run on AutoDL and the raw logs are retained.
## Attribution
This repository is a derivative of [jingyaogong/minimind](https://github.com/jingyaogong/minimind) under Apache-2.0. The extension preserves upstream model names and checkpoint compatibility; presentation-layer identity prompts are kept neutral.

View File

@ -250,7 +250,7 @@ if not MODEL_PATHS:
# 模型选择 # 模型选择
selected_model = st.sidebar.selectbox('Model', list(MODEL_PATHS.keys()), index=0) selected_model = st.sidebar.selectbox('Model', list(MODEL_PATHS.keys()), index=0)
model_path = MODEL_PATHS[selected_model][0] model_path = MODEL_PATHS[selected_model][0]
slogan = f"我是 {MODEL_PATHS[selected_model][1]},有什么可以帮你的?" if st.session_state.get('lang', 'en') == 'zh' else f"I am {MODEL_PATHS[selected_model][1]}, how can I help you?" slogan = "轻量级语言模型实验助手" if st.session_state.get('lang', 'en') == 'zh' else "Lightweight Language Model Assistant"
st.sidebar.markdown('<hr style="margin: 12px 0 16px 0;">', unsafe_allow_html=True) st.sidebar.markdown('<hr style="margin: 12px 0 16px 0;">', unsafe_allow_html=True)
@ -285,12 +285,9 @@ with st.sidebar.expander(get_text('tools')):
if checked and len(st.session_state.selected_tools) < 4: if checked and len(st.session_state.selected_tools) < 4:
st.session_state.selected_tools.append(name) st.session_state.selected_tools.append(name)
image_url = "https://www.modelscope.cn/api/v1/studio/gongjy/MiniMind/repo?Revision=master&FilePath=images%2Flogo2.png&View=true"
st.markdown( st.markdown(
f'<div style="display: flex; flex-direction: column; align-items: center; text-align: center; margin: 0; padding: 0;">' f'<div style="display: flex; flex-direction: column; align-items: center; text-align: center; margin: 0; padding: 0;">'
'<div style="font-style: italic; font-weight: 900; margin: 0; padding-top: 4px; display: flex; align-items: center; justify-content: center; flex-wrap: wrap; width: 100%;">' '<div style="font-style: italic; font-weight: 900; margin: 0; padding-top: 4px; display: flex; align-items: center; justify-content: center; flex-wrap: wrap; width: 100%;">'
f'<img src="{image_url}" style="width: 40px; height: 40px; "> '
f'<span style="font-size: 26px; margin-left: 10px;">{slogan}</span>' f'<span style="font-size: 26px; margin-left: 10px;">{slogan}</span>'
'</div>' '</div>'
f'<span style="color: #bbb; font-style: italic; margin-top: 6px; margin-bottom: 10px;">{get_text("disclaimer")}</span>' f'<span style="color: #bbb; font-style: italic; margin-top: 6px; margin-bottom: 10px;">{get_text("disclaimer")}</span>'
@ -348,7 +345,7 @@ def main():
setup_seed(random_seed) setup_seed(random_seed)
tools = [t for t in TOOLS if t['function']['name'] in st.session_state.get('selected_tools', [])] or None tools = [t for t in TOOLS if t['function']['name'] in st.session_state.get('selected_tools', [])] or None
sys_prompt = [] if tools else [{"role": "system", "content": "你是MiniMind,一个乐于助人、知识渊博的AI助手。请用完整且友好的方式回答用户问题。"}] sys_prompt = [] if tools else [{"role": "system", "content": "你是一个用于轻量语言模型实验的AI助手。请准确、完整且友好地回答用户问题,不要虚构开发者或个人身份。"}]
st.session_state.chat_messages = sys_prompt + st.session_state.chat_messages[-(st.session_state.history_chat_num + 1):] st.session_state.chat_messages = sys_prompt + st.session_state.chat_messages[-(st.session_state.history_chat_num + 1):]
template_kwargs = {"tokenize": False, "add_generation_prompt": True} template_kwargs = {"tokenize": False, "add_generation_prompt": True}
if st.session_state.get('enable_thinking', False): if st.session_state.get('enable_thinking', False):