Files
wehub-resource-sync 2aaeece67c
Codestyle Check / Lint (push) Has been cancelled
Codestyle Check / Check bypass (push) Has been cancelled
Pipelines-Test / Pipelines-Test (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:37:14 +08:00

326 lines
13 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 代码生成:写代码的 AI 助理
**目录**
- [代码生成](#代码生成)
- [简介](#简介)
- [特色](#特色)
- [效果展示](#效果展示)
- [Github Copilot 插件配置](#GithubCopilot 插件配置)
- [环境依赖](#环境依赖)
- [代码结构说明](#代码结构说明)
- [启动服务](#启动服务)
- [配置参数](#配置参数说明)
- [测试服务](#测试服务)
- [配置插件](#配置插件)
- [注意事项](#注意事项)
- [训练定制](#训练定制)
- [数据准备](#数据准备)
- [从本地文件创建数据集](#从本地文件创建数据集)
- [模型训练](#模型训练)
- [TaskFlow 调用](#TaskFlow 调用)
- [更多使用案例](#更多使用案例)
- [模型列表](#模型列表)
- [References](#references)
## 简介
代码生成是根据编程人员的输入,生成出编程人员想要的代码,能够帮助编程人员甚至独立生成代码,提高编程效率。
### 特色
本项目是基于预训练语言模型 CodeGen 的代码生成,具有以下优势:
- **效果领先**。CodeGen16B)在 HumanEval benchmark 上评估指标已经超过[OpenAI's Codex](https://arxiv.org/pdf/2107.03374.pdf)。
- **免费的 Github Copilot**。支持通过 Github Copilot 调用该模型,让你免费体验代码 AI 助理。
- **支持自定义数据集训练**。可增加自己的代码数据加以微调,让其更智能。
- **开箱即用**。本项目提供 TaskFlow 接口,无需训练,仅需几行代码便可预测。
## 效果展示
- Github Copilot 代码提示效果展示
<p align="center">
<img src="https://user-images.githubusercontent.com/24390500/189046785-6c04a3c3-ce89-4684-9aff-a7dc2e7a7041.gif"/> <br />
</p>
- 解算法题效果展示。求解无重复字符的最长子串的长度
```python
from paddlenlp import Taskflow
prompt = "def lengthOfLongestSubstring(self, s: str) -> int:"
codegen = Taskflow("code_generation", model="Salesforce/codegen-2B-mono",decode_strategy="greedy_search", repetition_penalty=1.0)
print(codegen(prompt))
```
结果输出为:
```python
if not s:
return 0
start = 0
end = 0
max_len = 0
while end < len(s):
if s[end] not in s[start:end]:
max_len = max(max_len, end - start + 1)
end += 1
else:
start += 1
return max_len
```
<p align="center">
<img src="https://user-images.githubusercontent.com/24390500/182512164-946d959c-57b1-49e6-b9a5-be47281d1ee2.png"/> <br />
</p>
## Jupyter Lab 插件配置
请参考[codegenJupyterLabExt](https://github.com/chenqianhe/codegenJupyterLabExt), 感谢生态开发者[@chenqianhe](https://github.com/chenqianhe)的贡献!👏👏
## GithubCopilot 插件配置
**以 VS Code 的插件为例**
### 环境依赖
- PaddleNLP >= 2.4.0
- PaddlePaddle >= 2.3.1
其他依赖:`pip install -r requirements.txt`
### 代码结构说明
以下是本项目主要代码结构及说明:
```text
codegen/
├── requirements.txt # 环境依赖
├── codegen_server.py # server启动脚本
├── run_clm.py # 训练评估脚本
├── run_clm.sh # 启动脚本
└── README.md # 说明文档
```
### 启动服务
```python
python codegen_server.py
```
##### 配置参数说明
在 codegen_server.py 中配置如下参数:
- `model_name_or_path`:模型名,默认为 "Salesforce/codegen-350M-mono"
- `device`:运行设备,默认为"gpu"
- `temperature`:解码参数 temperature,默认为0.5
- `top_k`:解码参数 top_k,默认为10
- `top_p`:解码参数 top_p,默认为1.0
- `repetition_penalty`:解码重复惩罚项,默认为1.0
- `min_length`:生成的最小长度,默认为0
- `max_length`:生成的最大长度,默认为16
- `decode_strategy`:解码策略,默认为"greedy_search"
- `use_fast`:是否使用 FastGeneration,可加速推理,默认为 True
- `use_fp16_decoding`:是否使用 fp16推理,可节省显存和加速推理,默认为 True
### 测试服务
```python
import openai
openai.api_key = 'dummy'
openai.api_base = 'http://127.0.0.1:8978'
result = openai.Completion.create(
engine='codegen', prompt='def hello', max_tokens=16, temperature=0.1)
print(result)
'''
<OpenAIObject text_completion id=cmpl-dmhoeHmcw9DJ4NeqOJDQVKv3iivJ0 at 0x7fe7a81d42c0> JSON: {
"id": "cmpl-dmhoeHmcw9DJ4NeqOJDQVKv3iivJ0",
"choices": [
{
"text": "_world():\n print(\"Hello World!\")\n\n\n#",
"index": 0,
"finish_reason": "stop",
"logprobs": null,
}
],
"usage": {
"completion_tokens": null,
"prompt_tokens": null,
"total_tokens": null
}
}
'''
```
**注意**:如果要从本地访问服务器,`127.0.0.1`需要换成服务器的对外 IP。
### 配置插件
打开用户设置([settings.json](https://code.visualstudio.com/docs/getstarted/settings#_settings-file-locations)),增加一行配置
```json
"github.copilot.advanced": {
"debug.overrideEngine": "codegen",
"debug.testOverrideProxyUrl": "http://127.0.0.1:8978",
"debug.overrideProxyUrl": "http://127.0.0.1:8978"
},
```
接下来就可以愉快地使用了😊。
#### 注意事项
- 如果使用 FastGeneration,需要设置[codegen_server.py](#配置参数说明)中`use_fast=True`,第一次推理会涉及到编译,会耗费一些时间。
- 如果要使用自己训练好的模型,可以设置[codegen_server.py](#配置参数说明)中`model_name_or_path`为本地模型路径。
- 如果要从本地访问服务器,上述的`127.0.0.1`需要换成服务器的对外 IP。
- 如果出现下方的提示和报错,则说明 FastGeneration 没有启动成功,需要定位下失败的原因。或者也可设置`use_fast=False`,不启动 FastGeneration 加速,但推理速度会较慢。
```shell
FastGeneration is not available, and the original version would be used instead.
```
```shell
RuntimeError: (NotFound) There are no kernels which are registered in the unsqueeze2 operator.
[Hint: Expected kernels_iter != all_op_kernels.end(), but received kernels_iter == all_op_kernels.end().] (at /home/Paddle/paddle/fluid/imperative/prepared_operator.cc:341)
[operator < unsqueeze2 > error]
```
- 本代码也支持插件[fauxpilot](https://marketplace.visualstudio.com/items?itemName=Venthe.fauxpilot),感谢[@linonetwo](https://github.com/linonetwo)测试。`settings.json`中配置"fauxpilot.server": "http://服务器 ip:8978/v1/engines"
## 训练定制
### 数据准备
#### 从本地文件创建数据集
在许多情况,我们需要使用本地数据集来训练我们的代码生成模型,本项目支持使用固定格式本地数据集文件进行训练。
本地数据集文件格式如下:
- train.json/test.json 文件格式:
每行为一个 jsonline
```text
{
"code": "from paddlenlp.transformers import CodeGenForCausalLM\n\n\nmodel = CodeGenForCausalLM.from_pretrained('Salesforce/codegen-2B-mono')\n"
}
```
更多数据集读取格式详见[数据集加载](https://paddlenlp.readthedocs.io/zh/latest/data_prepare/dataset_load.html#)和[自定义数据集](https://paddlenlp.readthedocs.io/zh/latest/data_prepare/dataset_self_defined.html)。
### 模型训练
运行如下命令即可在样例训练集上进行 finetune,并在样例验证集上进行验证。
```shell
# GPU启动,参数`--gpus`指定训练所用的GPU卡号,可以是单卡,也可以多卡
unset CUDA_VISIBLE_DEVICES
python -m paddle.distributed.launch --gpus 0,1 run_clm.py \
--model_name_or_path Salesforce/codegen-350M-mono \
--block_size 1024 \
--output_dir output \
--train_file train.json \
--validation_file test.json \
--num_train_epochs 5 \
--logging_steps 10 \
--save_steps 1000 \
--per_device_train_batch_size 2 \
--per_device_eval_batch_size 2 \
--learning_rate 1e-4 \
--warmup_ratio 0.1 \
--do_train \
--do_eval \
--device gpu
```
使用多卡训练可以指定多个 GPU 卡号,例如 --gpus "0,1"
关键参数释义如下:
- `gpus` 指示了训练所用的 GPU 卡号。
- `model_name_or_path` 指示了 finetune 使用的具体预训练模型,可以是 PaddleNLP 提供的预训练模型(详见[模型列表](#模型列表)),或者是本地的预训练模型。如果使用本地的预训练模型,可以配置本地模型的目录地址,例如: ./checkpoints/model_xx/,目录中需包含 paddle 预训练模型 model_state.pdparams。如果使用 PaddleNLP 提供的预训练模型,可以选择下面其中之一。
- `block_size` 表示训练时候数据被拆分的块数。
- `output_dir` 表示模型的保存路径。
- `train_file` 本地训练数据地址,数据格式必须与`dataset_name`所指数据集格式相同。
- `validation_file` 本地测试数据地址,数据格式必须与`dataset_name`所指数据集格式相同。
- `num_train_epochs` 表示训练轮数。
- `logging_steps` 表示日志打印间隔。
- `save_steps` 表示模型保存及评估间隔。
- `per_device_train_batch_size` 表示训练时**每张卡**上的样本数目。
- `per_device_eval_batch_size` 表示测试时**每张卡**上的样本数目。
- `learning_rate` 表示基础学习率大小,将于 learning rate scheduler 产生的值相乘作为当前学习率。
- `warmup_ratio` 表示学习率逐渐升高到基础学习率(即上面配置的 learning_rate)所需要的迭代数占总步数的比例,最早的使用可以参考[这篇论文](https://arxiv.org/pdf/1706.02677.pdf)。
- `do_train` 表示是否训练。
- `do_eval` 表示是否评测。
- `device` 表示使用的设备,从 gpu 和 cpu 中选择。
可通过`bash run_clm.sh`启动训练,更多参数详情和参数的默认值请参考`run_clm.py`
程序运行时将会自动进行训练和验证,训练过程中会自动保存模型在指定的`save_dir`中。
如:
```text
./output/
│── model_config.json
│── model_state.pdparams
│── tokenizer_config.json
│── special_tokens_map.json
│── added_tokens.json
│── vocab.json
│── merges.txt
└── ...
```
**NOTE:** 如需恢复模型训练,`model_name_or_path`配置本地模型的目录地址即可。
## TaskFlow 调用
参考[TaskFlow 文档](https://github.com/PaddlePaddle/PaddleNLP/blob/develop/docs/zh/model_zoo/taskflow.md)
## 更多使用案例
- 根据注释/功能描述写代码
```python
import re
import paddle
from paddlenlp.transformers import CodeGenTokenizer, CodeGenForCausalLM
# The supported models are shown in the following table
model_name = 'Salesforce/codegen-2B-mono'
# Init tokenizer
tokenizer = CodeGenTokenizer.from_pretrained(model_name)
# Init model
model = CodeGenForCausalLM.from_pretrained(model_name)
prompt = "# this function prints hello world"
inputs = tokenizer([prompt])
inputs = {k: paddle.to_tensor(v) for (k, v) in inputs.items()}
# Generate
output, score = model.generate(inputs['input_ids'],
max_length=128,
decode_strategy='greedy_search')
# Decode the result
print(
tokenizer.decode(output[0],
truncate_before_pattern=[r"\n\n^#", "^'''", "\n\n\n"],
skip_special_tokens=True,
spaces_between_special_tokens=False))
```
结果输出为:
```python
def hello_world():
print("Hello World")
hello_world()
```
## 模型列表
模型列表
| 模型名称 | 说明 |
| :--------------------------------- | -------------------------------- |
| Salesforce/codegen-350M-mono | 基于 Python 数据集 BIGPYTHON 训练 |
| Salesforce/codegen-2B-mono | 基于 Python 数据集 BIGPYTHON 训练 |
| Salesforce/codegen-6B-mono | 基于 Python 数据集 BIGPYTHON 训练 |
| Salesforce/codegen-16B-mono | 基于 Python 数据集 BIGPYTHON 训练 |
| Salesforce/codegen-350M-nl | 基于自然语言数据集 THEPILE 训练 |
| Salesforce/codegen-2B-nl | 基于自然语言数据集 THEPILE 训练 |
| Salesforce/codegen-6B-nl | 基于自然语言数据集 THEPILE 训练 |
| Salesforce/codegen-16B-nl | 基于自然语言数据集 THEPILE 训练 |
| Salesforce/codegen-350M-multi | 基于多编程语言数据集 BIGQUERY 训练 |
| Salesforce/codegen-2B-multi | 基于多编程语言数据集 BIGQUERY 训练 |
| Salesforce/codegen-6B-multi | 基于多编程语言数据集 BIGQUERY 训练 |
| Salesforce/codegen-16B-multi | 基于多编程语言数据集 BIGQUERY 训练 |
## References
- Nijkamp, Erik, et al. "A conversational paradigm for program synthesis." arXiv preprint arXiv:2203.13474 (2022).
- [https://github.com/features/copilot/](https://github.com/features/copilot/)
- [https://github.com/AndPuQing/Papilot](https://github.com/AndPuQing/Papilot)