|
| 1 | +# aiXcoder-7B Code Large Language Model |
| 2 | + |
| 3 | +<p align="center"> |
| 4 | + 🏠 <a href="https://www.aixcoder.com/" target="_blank">官网</a>|🛠 <a href="https://marketplace.visualstudio.com/items?itemName=aixcoder-plugin.aixcoder" target="_blank">VS Code 插件</a>|🛠 <a href="https://plugins.jetbrains.com/plugin/13574-aixcoder-code-completer" target="_blank">Jetbrains 插件</a>|🤗 <a href="https://huggingface.co/aiXcoder/aiXcoder-7b" target="_blank">模型下载</a>|<a href="" target="_blank">技术交流群</a>|<a href="./assets/wechat_2.jpg" target="_blank">公众号</a> |
| 5 | +</p> |
| 6 | + |
| 7 | +欢迎来到aiXcoder-7B代码大型语言模型的官方仓库。该模型旨在理解和生成多种编程语言中的代码,提供在代码完成、理解、生成以及更多关于编程语言的任务中的最先进性能。 |
| 8 | + |
| 9 | +目录 |
| 10 | + |
| 11 | +1. [模型简介](#模型简介) |
| 12 | +2. [快速上手](#快速上手) |
| 13 | + - [运行环境](#运行环境) |
| 14 | + - [模型权重](#模型权重) |
| 15 | + - [推理示例](#推理示例) |
| 16 | +3. [aiXcoder 7B 训练数据](#aixcoder-7b-训练数据) |
| 17 | +4. [训练](#训练) |
| 18 | + - [训练超参数](#训练超参数) |
| 19 | + <!-- - [批量数据组织方式](#批量数据组织方式) |
| 20 | + - [预训练任务](#预训练任务) --> |
| 21 | +5. [实验结果](#实验结果) |
| 22 | + - [NL2Code 基准测试](#nl2code-基准测试) |
| 23 | + - [代码补全 (Fill in the Middle)](#代码补全-fill-in-the-middle) |
| 24 | + - [跨文件代码生成](#跨文件代码生成) |
| 25 | +6. [License](#license) |
| 26 | +7. [Acknowledgments](#acknowledgments) |
| 27 | + |
| 28 | + |
| 29 | + |
| 30 | +## 模型简介 |
| 31 | + |
| 32 | +随着代码大模型的能力逐渐被挖掘出来,aiXcoder 也一直在思考怎样才能令代码大模型在实际开发场景中有更大的帮助。为此,我们开源了 aiXcoder 7B Base,该模型在1.2T Unique Tokens上做了大量的训练,并且该模型的预训练任务及上下文信息都为真实代码生成场景做了独特的设计。 |
| 33 | + |
| 34 | +aiXcoder 7B Base 在代码补全场景下是所有同等级参数量模型中效果最好的,主流多语言nl2code benchmark 平均上效果也超过codellama 34B 和StarCoder2 15B。 |
| 35 | + |
| 36 | +在我们持续推动代码大模型应用的探索过程中,aiXcoder 7B Base 模型的发布标志着一个重要的里程碑。当前版本的 aiXcoder 7B Base 是一个基础模型,专注于提升代码补全和代码生成的效率与准确性,旨在为开发人员在这些场景下提供强有力的支持。值得注意的是,这个版本尚未经过特别的instruct微调,意味着它在特定的高级任务如测试用例生成和代码调试方面可能还未达到最优表现。 |
| 37 | + |
| 38 | +然而,我们已经在规划中包含了对aiXcoder模型系列的进一步发展。在不久的将来,我们计划发布新的模型版本,这些版本将经过精心的Instruct微调,专门针对更广泛的编程任务,包括但不限于测试用例生成和代码调试。通过这些经过Instruct微调的模型,我们期待能够为开发者提供更全面、更深入的编程支持,帮助他们在软件开发的每一个阶段都能发挥出最大的效率。 |
| 39 | + |
| 40 | + |
| 41 | +> aiXcoder 7B surpasses mainstream models in nl2code benchmark. |
| 42 | +
|
| 43 | +<br> |
| 44 | +<br> |
| 45 | + |
| 46 | + |
| 47 | +> aiXcoder 7B surpasses mainstream models in nl2code benchmark. aiXcoder-7B is an enhancement of aiXcoder-7B-Base, fine-tuned on one hundred thousand data entries similar to Evol-instruct for one epoch. |
| 48 | +
|
| 49 | +<br> |
| 50 | +<br> |
| 51 | + |
| 52 | +## 快速上手 |
| 53 | + |
| 54 | +### 运行环境 |
| 55 | + |
| 56 | +#### 选择一:构建一个运行环境 |
| 57 | + |
| 58 | +主要的环境依赖为: |
| 59 | + |
| 60 | +- Python 3.8 or higher |
| 61 | +- PyTorch 2.1.0 or higher |
| 62 | +- sentencepiece 0.2.0 or higher |
| 63 | +- transformers 4.34.1 or higher (if run inference by transformers library) |
| 64 | + |
| 65 | +在支持CUDA环境的宿主机或者容器内,执行以下命令安装环境依赖项: |
| 66 | + |
| 67 | +```bash |
| 68 | +conda create -n aixcoder-7b python=3.11 |
| 69 | +conda activate aixcoder-7b |
| 70 | +git clone git@github.com:aixcoder-plugin/aiXcoder-7b.git |
| 71 | +cd aiXcoder-7b |
| 72 | +pip install -r requirements.txt |
| 73 | +``` |
| 74 | + |
| 75 | +`requirements.txt` 列举了所有的依赖项及其版本号。 |
| 76 | + |
| 77 | +如果想要加快推理速度,我们强烈建议安装 FlashAttention 库(可选)。在确定您的芯片版本与CUDA版本支持FlashAttention 的条件下,可通过以下步骤进行安装: |
| 78 | + |
| 79 | +```bash |
| 80 | +git clone git@github.com:Dao-AILab/flash-attention.git |
| 81 | +cd flash-attention |
| 82 | +MAX_JOBS=8 python setup.py install |
| 83 | +``` |
| 84 | + |
| 85 | +#### Option 2: Docker |
| 86 | + |
| 87 | +为了更好地隔离开发环境,我们建议您可以在 Docker 容器内运行模型推理。如下是启动准备 docker 环境的步骤: |
| 88 | + |
| 89 | +1. 安装 Docker:如果您的机器还没有安装Docker,您可以参考官方的安装步骤安装。 |
| 90 | + |
| 91 | +2. 拉取镜像: 从 Docker Hub 拉取 PyTorch 镜像。 |
| 92 | + |
| 93 | +```bash |
| 94 | +docker pull pytorch/pytorch:2.1.0-cuda11.8-cudnn8-devel |
| 95 | +``` |
| 96 | + |
| 97 | +3. 启动容器: 拉取docker 镜像后,可以启动容器,并在容器中运行模型。 |
| 98 | + |
| 99 | +```bash |
| 100 | +docker run --gpus all -it -v /dev/shm:/dev/shm --name aix_instance pytorch/pytorch:2.1.0-cuda11.8-cudnn8-devel /bin/bash |
| 101 | +pip install sentencepiece |
| 102 | +git clone git@github.com:aixcoder-plugin/aiXcoder-7b.git |
| 103 | +cd aiXcoder-7b |
| 104 | +``` |
| 105 | + |
| 106 | +如果想要加快推理速度,我们强烈建议安装 FlashAttention 库(可选)。在确定您的芯片版本与CUDA版本支持FlashAttention 的条件下,可通过以下步骤进行安装: |
| 107 | + |
| 108 | +```bash |
| 109 | +git clone git@github.com:Dao-AILab/flash-attention.git |
| 110 | +cd flash-attention |
| 111 | +MAX_JOBS=8 python setup.py install |
| 112 | +``` |
| 113 | + |
| 114 | +4. 模型推理: 在容器内,您可以安装推理示例代码进行预测。 |
| 115 | + |
| 116 | + |
| 117 | +### 模型权重 |
| 118 | + |
| 119 | +您能从以下地址下载模型: |
| 120 | + |
| 121 | +- [aiXcoder Base Download](https://huggingface.co/aiXcoder/aiXcoder-7b) |
| 122 | +- aiXcoder Instruct Download (Comming soon...) |
| 123 | + |
| 124 | +### 推理示例 |
| 125 | + |
| 126 | +#### 命令行执行 |
| 127 | + |
| 128 | +如果需要快速执行,只需要通过以下命令行即可运行推理样本: |
| 129 | + |
| 130 | +```bash |
| 131 | +torchrun --nproc_per_node 1 sess_megatron.py --model-dir "path/to/model_weights_dir" |
| 132 | +``` |
| 133 | + |
| 134 | +将 "path/to/model_weights_dir"替换为您下载模型权重后的本地地址。 |
| 135 | + |
| 136 | +#### Python 脚本 |
| 137 | + |
| 138 | +如果您想嵌入自己的工具流,或者获得更灵活的使用方式,您能通过以下代码直接调用: |
| 139 | + |
| 140 | +```python |
| 141 | + |
| 142 | +from sess_megatron import TestInference |
| 143 | + |
| 144 | +infer = TestInference() |
| 145 | +res = infer.run_infer( |
| 146 | + # for FIM style input, code_string stands for prefix context |
| 147 | + code_string="""# 快速排序算法""", |
| 148 | + # for FIM style input, later_code stands for suffix context |
| 149 | + later_code="\n", |
| 150 | + # file_path should be a path from project to file |
| 151 | + file_path="test.py", |
| 152 | + # max num for generated tokens |
| 153 | + max_new_tokens=256, |
| 154 | +) |
| 155 | +print(res) |
| 156 | + |
| 157 | +"""output: |
| 158 | +
|
| 159 | +def quick_sort(arr): |
| 160 | + if len(arr) <= 1: |
| 161 | + return arr |
| 162 | + pivot = arr[0] |
| 163 | + less = [i for i in arr[1:] if i <= pivot] |
| 164 | + greater = [i for i in arr[1:] if i > pivot] |
| 165 | + return quick_sort(less) + [pivot] + quick_sort(greater) |
| 166 | +
|
| 167 | +
|
| 168 | +# 测试 |
| 169 | +arr = [3, 2, 1, 4, 5] |
| 170 | +print(quick_sort(arr)) # [1, 2, 3, 4, 5] |
| 171 | +""" |
| 172 | + |
| 173 | +``` |
| 174 | + |
| 175 | + |
| 176 | +```python |
| 177 | + |
| 178 | +import torch |
| 179 | +import sys |
| 180 | +from hf_mini.utils import input_wrapper |
| 181 | +from transformers import AutoModelForCausalLM, AutoTokenizer |
| 182 | + |
| 183 | +device = "cuda" # the device to load the model onto |
| 184 | + |
| 185 | +tokenizer = AutoTokenizer.from_pretrained("aiXcoder/aiXcoder-7b") |
| 186 | +model = AutoModelForCausalLM.from_pretrained("aiXcoder/aiXcoder-7b", torch_dtype=torch.bfloat16) |
| 187 | + |
| 188 | + |
| 189 | +text = input_wrapper( |
| 190 | + # for FIM style input, code_string stands for prefix context |
| 191 | + code_string="# 快速排序算法", |
| 192 | + # for FIM style input, later_code stands for suffix context |
| 193 | + later_code="\n# 测试\narr = [3, 2, 1, 4, 5]\nprint(quick_sort(arr)) # [1, 2, 3, 4, 5]", |
| 194 | + # file_path should be a path from project to file |
| 195 | + path="test.py" |
| 196 | +) |
| 197 | + |
| 198 | +if len(text) == 0: |
| 199 | + sys.exit() |
| 200 | + |
| 201 | +inputs = tokenizer(text, return_tensors="pt", return_token_type_ids=False) |
| 202 | + |
| 203 | +inputs = inputs.to(device) |
| 204 | +model.to(device) |
| 205 | + |
| 206 | +outputs = model.generate(**inputs, max_new_tokens=256) |
| 207 | +print(tokenizer.decode(outputs[0], skip_special_tokens=False)) |
| 208 | + |
| 209 | + |
| 210 | + |
| 211 | +"""output: |
| 212 | +def quick_sort(arr): |
| 213 | + # 如果数组长度小于等于1,直接返回 |
| 214 | + if len(arr) <= 1: |
| 215 | + return arr |
| 216 | + # 选择数组的第一个元素作为基准 |
| 217 | + pivot = arr[0] |
| 218 | + # 初始化左右指针 |
| 219 | + left, right = 1, len(arr) - 1 |
| 220 | + # 循环直到左指针小于右指针 |
| 221 | + while left < right: |
| 222 | + # 从右到左找到第一个小于基准的元素,与左指针元素交换 |
| 223 | + if arr[right] < pivot: |
| 224 | + arr[left], arr[right] = arr[right], arr[left] |
| 225 | + left += 1 |
| 226 | + # 从左到右找到第一个大于等于基准的元素,与右指针元素交换 |
| 227 | + if arr[left] >= pivot: |
| 228 | + right -= 1 |
| 229 | + # 将基准元素与左指针元素交换 |
| 230 | + arr[left], arr[0] = arr[0], arr[left] |
| 231 | + # 对左半部分进行递归排序 |
| 232 | + quick_sort(arr[:left]) |
| 233 | + # 对右半部分进行递归排序 |
| 234 | + quick_sort(arr[left + 1:]) |
| 235 | + return arr</s> |
| 236 | +""" |
| 237 | + |
| 238 | +``` |
| 239 | + |
| 240 | +## aiXcoder 7B 训练数据 |
| 241 | + |
| 242 | +aiXcoder 的数据分为核心数据集与扩展数据集,核心数据集由业务上常用的几大编程语言,以及与代码息息相关的自然语言组成。核心数据集的编程语言主要有 C++、Python、Java、JavaScript等近百种主流编程语言,自然语言上主要由 StackOverFlow 问答、技术博客、代码文档、计算机领域论文等组成。扩展数据集主要由过滤后的代码开源数据集,英文自然语言高质量数据集,中文自然语言高质量数据集组成。 |
| 243 | + |
| 244 | +<!-- <br> |
| 245 | +<br> |
| 246 | +
|
| 247 | + |
| 248 | +
|
| 249 | +<br> |
| 250 | +<br> --> |
| 251 | + |
| 252 | + |
| 253 | +aiXcoder 核心数据集主要用于强化代码大模型在以上编程语言上的效果,其经过大量的过滤与筛选过程。具体而言主要分为如下几步:1) 原始数据挑选; 2) 对项目进行综合排序,并筛选;3) 基于 MinHashes(Broder, 2000) 等方法进行代码去重、去除自动生成的代码;4) 个人敏感信息识别与处理;5) 清理被注释的代码;6) 语法分析过滤不正确或者异常的代码文件;7)结合静态分析工具,检测并排除 Java\CPP\Python\JS 等主流编程语言中高风险的163 种 bug 和197 种缺陷。 |
| 254 | + |
| 255 | +1. 原始数据挑选 |
| 256 | + - 排除 copyleft licenses 项目 |
| 257 | + - 对 aiXcoder 在各大代码托管平台上抓取的数据及开源数据做项目去重 |
| 258 | +2. 项目级的综合排序 |
| 259 | + - 统计项目的Star量、Git Commit 数量、Test文件数量,并综合评分 |
| 260 | + - 排除综合评分最低的10%数据 |
| 261 | +3. 代码文件级筛选 |
| 262 | + - 删除自动生成代码 |
| 263 | + - near-deduplication去重 |
| 264 | +4. 敏感信息去除 |
| 265 | + - 命名实体模型识别并删除人名、IP、账号密码、网址等敏感信息 |
| 266 | +5. 被注释的代码 |
| 267 | + - 按比例随机删除被注释的大段代码 |
| 268 | +6. 语法分析 |
| 269 | + - 删除主流数十种语言存在语法解析错误或者语法错误的代码 |
| 270 | +7. 静态分析 |
| 271 | + - 结合静态分析工具,扫描并定位影响代码可靠性和可维护性的161种Bug,影响代码安全性的197种漏洞 |
| 272 | + |
| 273 | +```python |
| 274 | +# "__init__" method should not return a value |
| 275 | + |
| 276 | +# Noncompliant: a TypeError will be raised |
| 277 | +class MyClass(object): |
| 278 | + def __init__(self): |
| 279 | + self.message = 'HelloWorld' |
| 280 | + return self |
| 281 | + |
| 282 | +# Compliant solution |
| 283 | +class MyClass(object): |
| 284 | + def __init__(self): |
| 285 | + self.message = 'HelloWorld' |
| 286 | +``` |
| 287 | + |
| 288 | +上述代码展示了python中的一种bug模式,即 __init__ 方法不应该返回值。 |
| 289 | + |
| 290 | +## 训练 |
| 291 | + |
| 292 | +### 训练超参数 |
| 293 | + |
| 294 | +分词器: |
| 295 | +- 基于字节码的 BPE 分词器 |
| 296 | +- 词表大小:49,152 |
| 297 | + |
| 298 | +模型结构: |
| 299 | +- RoPE (Rotary Positional Embedding) 相对位置编码 |
| 300 | +- 中间全连接层采用 SwiGLU |
| 301 | +- Grouped Query Attention |
| 302 | + |
| 303 | +训练配置: |
| 304 | +- 70% 为结构化 FIM (Fill in the middle)训练任务,30% 为自回归语言模型任务; |
| 305 | +- BFlot 16 数据类型 |
| 306 | +- AdamW 优化器,学习率最大1e-5,最小 1e-6,采用余弦衰减 |
| 307 | +- 预训练长度为 32,768 |
| 308 | + |
| 309 | + |
| 310 | +## 实验结果 |
| 311 | + |
| 312 | +### NL2Code 基准测试 |
| 313 | + |
| 314 | +表1 展示了 aiXcoder-7B Base 模型在独立方法生成基准上的表现,我们的模型在各大预训练基础模型中表现很好,在百亿级参数量下拥有当前最好的效果。 |
| 315 | + |
| 316 | + |
| 317 | + |
| 318 | + |
| 319 | +### 代码补全 (Fill in the Middle) |
| 320 | + |
| 321 | +与 Table 1 的 Stand alone nl2code 不同,在实际编程场景中,我们更需要考虑光标上下文的代码补全能力。一般而言,各种开源代码大模型都会考虑在预训练中加入Fill in the middle(FIM) 模式,来强化模型在考虑代码上下文的场景下生成更准确的结果。为此,我们将以FIM为默认代码补全方式,评测各个模型在实际编程场景中的能力。 |
| 322 | + |
| 323 | +当前考虑上下文的代码补全,主流评测集是 Santacoder(Ben Allal et al., 2023) 提出来的单行评测方法。该评测集会从HumanEval 或者 MultiPL-E 中抽取的单行代码,然后在给定完整的上文与下文条件下,评估模型生成结果的Exact Match指标。 |
| 324 | + |
| 325 | + |
| 326 | + |
| 327 | + |
| 328 | +为了进一步精细地评测代码大模型在代码补全上的能力,aiXcoder 构建了一个数据量更大,被测代码多样性更高、被测代码上下文长度更长、更接近实际开发项目的评测集,该评测集也将同步在GitHub上开源。在评估过程中,我们保证不同代码大模型之间采用相同的16K最大序列长度,并且评估不同场景下的生成效果,例如生成完整方法块、条件判断块、循环处理块、异常捕捉块等十三种情况。 |
| 329 | + |
| 330 | +Table 3 展示了不同模型在不同语言上的平均生成效果,最终的评估结果是所有补全场景与评测样本的均值。aiXcoder 7B Base 模型在各大编程语言,各种评估标准下都是效果最好的,这表明aiXcoder 7B Base 在最基础的代码补全能力上是所有同量级开源模型最好的,最适合用于实际编程场景中提供代码补全能力的基础模型。 |
| 331 | + |
| 332 | + |
| 333 | + |
| 334 | +对于 Table 3 中每一条评测结果,其都有更为详细的评测维度。Table 4 到 7 展示了不同模型在不同语言上多维度评估的细节: |
| 335 | + |
| 336 | +- **Method signature**: 表示模型根据上下文生成方法签名; |
| 337 | +- **Method body**: 表示模型根据上下文,包括函数签名,生成完整的方法体; |
| 338 | +- **Single line**: 表示单行代码补全; |
| 339 | +- **Method with comment**: 表示根据上下文,包括函数签名与函数注释,生成对应的函数体; |
| 340 | +- **Empty**: 表示在上下文完整的情况下,模型需要预测为空; |
| 341 | +- **Method body top, mid, bottom**: 表示分别在函数体上半部分,函数体中间部分,函数体下半部分的代码生成效果; |
| 342 | +- **If, for, while, try, switch statement**: 表示生成条件代码块、循环代码块、异常捕捉代码块、条件分支代码块的效果; |
| 343 | + |
| 344 | + |
| 345 | + |
| 346 | + |
| 347 | + |
| 348 | + |
| 349 | + |
| 350 | + |
| 351 | + |
| 352 | + |
| 353 | +### 跨文件代码生成 |
| 354 | + |
| 355 | +代码大模型另一个比较重要的能力是跨文件的代码上下文理解能力,因为开发者在实际编写项目中,经常需要考虑当前项目其它文件内的信息。因此我们采用了CrossCodeEval (Ding et al., 2023)评测集,来评估模型提取跨文件上下文信息的能力。 |
| 356 | + |
| 357 | +在 Table 8 中,首先作为 Baseline,在单文件的情况下评测各代码大模型的生成能力。然后在 BM25 为相似性指标的情况下,通过上文搜索项目内相似的代码并作为prompt,再次评估模型的生成效果。最后,w/Ref. 表示假设我们知道正确的References 代码是什么样的,然后通过 References 搜索项目内相似的代码作为prompt,再次评估模型的生成效果。最终 aiXcoder-7B 模型在所有语言上的效果都是很好的,这证明了我们模型在提取上下文信息上,尤其是跨文件的上下文信息的能力。 |
| 358 | + |
| 359 | + |
| 360 | + |
| 361 | + |
| 362 | +## License |
| 363 | + |
| 364 | + |
| 365 | +The source code in this repository is licensed under the [Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0) License - see the LICENSE file for details. |
| 366 | +The model weights are licensed under the [Model License](./MODEL_LICENSE) for academic research use; for commercial use, please apply by sending an email to support@aixcoder.com. |
| 367 | + |
| 368 | + |
| 369 | +## Acknowledgments |
| 370 | + |
| 371 | +We would like to thank all contributors to the open-source projects and datasets that made this work possible. |
| 372 | + |
| 373 | +For any questions or issues, please open an issue on this repository. |
| 374 | + |
| 375 | +Thank you for your interest in our Code Large Language Model. We look forward to your contributions and feedback! |
0 commit comments