# CodeBert复现实战 **Repository Path**: thinkerhui/codebert ## Basic Information - **Project Name**: CodeBert复现实战 - **Description**: 大模型大创CodeBert复现实战项目仓库,复现对象的仓库:https://github.com/microsoft/CodeBERT - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2024-01-30 - **Last Updated**: 2024-02-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # CodeBert复现实战 #### 介绍 大模型大创CodeBert复现实战项目仓库,复现对象的仓库:https://github.com/microsoft/CodeBERT 鉴于我们大创的研究方向,这里先只复现代码搜索的下游任务。 ### 项目创建 ```shell git clone https://gitee.com/thinkerhui/codebert.git cd codebert mkdir unixcoder-base ``` 然后从huggingface下载模型: [microsoft/unixcoder-base at main (huggingface.co)](https://huggingface.co/microsoft/unixcoder-base/tree/main)把这里目录的所有文件都下载到unixcoder-base目录里面,任意下载方式都可以,怎么方便怎么下。 ### 数据集下载 注意下面的数据集下载命令和README的命令有所区别,这是因为windows下的wget和linux下的wget有所不同,我发现如果windows下不用`-O filepath`参数的话默认就不保存,所以要加上。 ``` mkdir dataset cd dataset mkdir cosqa cd cosqa wget https://github.com/Jun-jie-Huang/CoCLR/raw/main/data/search/code_idx_map.txt -O code_idx_map.txt wget https://github.com/Jun-jie-Huang/CoCLR/raw/main/data/search/cosqa-retrieval-dev-500.json -O cosqa-retrieval-dev-500.json wget https://github.com/Jun-jie-Huang/CoCLR/raw/main/data/search/cosqa-retrieval-test-500.json -O cosqa-retrieval-test-500.json wget https://github.com/Jun-jie-Huang/CoCLR/raw/main/data/search/cosqa-retrieval-train-19604.json -O cosqa-retrieval-train-19604.json ``` ### 运行 安装完成之后可以跑一下test_decoding.py和test_encoding.py来玩一下。这两个文件是我从微软CodeBert仓库的README中抄过去的。 CodeBert项目本身提供了完善的运行程序,能够以输入参数的形式来指定目录等参数。 比如下面的是zero_shot的测试运行代码,我感觉其中有些参数是用不到的: ```bash python run.py \ --output_dir saved_models/cosqa \ --model_name_or_path microsoft/unixcoder-base \ --do_zero_shot \ --do_test \ --test_data_file dataset/cosqa/cosqa-retrieval-test-500.json \ --codebase_file dataset/cosqa/code_idx_map.txt \ --num_train_epochs 10 \ --code_length 256 \ --nl_length 128 \ --train_batch_size 64 \ --eval_batch_size 64 \ --learning_rate 2e-5 \ --seed 123456 ``` **比较重要的参数:** `--output_dir`是运行训练/验证/测试时使用到的路径。实际过程中验证/测试并不会往里面存东西,只有在训练的时候会把训练得到的最好模型存储起来,验证/测试(非zero-shot)会从里面读取训练好的微调模型。 `--model_name_or_path`是模型所在的路径,要根据实际情况来修改。比如我把下载好的预训练模型存放在run.py的同一目录的unixcoder-base中,后面的路径就要改为`unixcoder-base` `--test_data_file`,`--codebase_file`这两个要指定上面所下载的数据集所在的路径。 `--num_train_epochs `指定训练几个轮回。 `--train_batch_size `调整训练时采样一个批次的大小,这个不能随意设置,要根据显卡的显存来调整,不然会爆掉。 我的项目运行的时候的结构:跑的时候运行的主要是model.py和run.py两个文件。 ![image-20240130103851177](https://sse-market-source-1320172928.cos.ap-guangzhou.myqcloud.com/blog/image-20240130103851177.png) 当然,上面的是linux的。结合windows终端的情况,可以用下面的命令来运行: ```shell python run.py --output_dir saved_models\cosqa --model_name_or_path unixcoder-base --do_zero_shot --do_test --test_data_file dataset\cosqa\cosqa-retrieval-test-500.json --codebase_file dataset\cosqa\code_idx_map.txt --num_train_epochs 10 --code_length 256 --nl_length 128 --train_batch_size 64 --eval_batch_size 64 --learning_rate 2e-5 --seed 123456 ``` 这个我直接跑了一下,似乎是需要先有训练才行?只有一个结果跑了出来。 查看代码最终确实只输出结果而不会输出或者保存中间过程的数据(比如哪些查询更好或者更坏)。 下面是非zero-shot的一些运行命令,称之为fine-tune微调出来的好模型: 官方README提供的命令: ```bash # Training python run.py \ --output_dir saved_models/cosqa \ --model_name_or_path microsoft/unixcoder-base \ --do_train \ --train_data_file dataset/cosqa/cosqa-retrieval-train-19604.json \ --eval_data_file dataset/cosqa/cosqa-retrieval-dev-500.json \ --codebase_file dataset/cosqa/code_idx_map.txt \ --num_train_epochs 10 \ --code_length 256 \ --nl_length 128 \ --train_batch_size 64 \ --eval_batch_size 64 \ --learning_rate 2e-5 \ --seed 123456 # Evaluating python run.py \ --output_dir saved_models/cosqa \ --model_name_or_path microsoft/unixcoder-base \ --do_eval \ --do_test \ --eval_data_file dataset/cosqa/cosqa-retrieval-dev-500.json \ --test_data_file dataset/cosqa/cosqa-retrieval-test-500.json \ --codebase_file dataset/cosqa/code_idx_map.txt \ --num_train_epochs 10 \ --code_length 256 \ --nl_length 128 \ --train_batch_size 64 \ --eval_batch_size 64 \ --learning_rate 2e-5 \ --seed 123456 ``` 适应windows终端的命令: ```shell # Training python run.py --output_dir saved_models\cosqa --model_name_or_path unixcoder-base --do_train --train_data_file dataset\cosqa\cosqa-retrieval-train-19604.json --eval_data_file dataset\cosqa\cosqa-retrieval-dev-500.json --codebase_file dataset\cosqa\code_idx_map.txt --num_train_epochs 10 --code_length 256 --nl_length 128 --train_batch_size 64 --eval_batch_size 64 --learning_rate 2e-5 --seed 123456 # Evaluating python run.py --output_dir saved_models\cosqa --model_name_or_path unixcoder-base --do_eval --do_test --eval_data_file dataset\cosqa\cosqa-retrieval-dev-500.json --test_data_file dataset\cosqa\cosqa-retrieval-test-500.json --codebase_file dataset\cosqa\code_idx_map.txt --num_train_epochs 10 --code_length 256 --nl_length 128 --train_batch_size 64 --eval_batch_size 64 --learning_rate 2e-5 --seed 123456 ``` 运行训练的时候出现了报错: ```shell torch.cuda.OutOfMemoryError: CUDA out of memory. Tried to allocate 48.00 MiB. GPU 0 has a total capacty of 8.00 GiB of which 0 bytes is free. Of the allocated memory 13.69 GiB is allocated by PyTorch, and 68.33 MiB is reserved by PyTorch but unallocated. If reserved but unallocated memory is large try setting max_split_size_mb to avoid fragmentation. See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF ``` 也就是显存爆掉了,尝试调整一下参数,`batch_size`调小了很多: ``` python run.py --output_dir saved_models\cosqa --model_name_or_path unixcoder-base --do_train --train_data_file dataset\cosqa\cosqa-retrieval-train-19604.json --eval_data_file dataset\cosqa\cosqa-retrieval-dev-500.json --codebase_file dataset\cosqa\code_idx_map.txt --num_train_epochs 10 --code_length 256 --nl_length 128 --train_batch_size 12 --eval_batch_size 12 --learning_rate 2e-5 --seed 123456 ``` 看来调整的这个batch_size对于显卡是相对比较合适的(应该还可以大一点),但是训练出的模型可能会受影响。 ![image-20240129160225522](https://sse-market-source-1320172928.cos.ap-guangzhou.myqcloud.com/blog/image-20240129162722965.png) ## 配置环境 上面默认是已经配好环境的,实际上要配置支持gpu加速的pytorch环境。如果没有支持加速的gpu的话直接安装pytorch和transformers就好。 我主要参考了:http://t.csdnimg.cn/YJBLp ### CUDA 输入`nvidia-smi`查看显卡信息。下载并安装对应版本的cuda toolkit. ![image-20240129133519772](https://sse-market-source-1320172928.cos.ap-guangzhou.myqcloud.com/blog/image-20240129133519772.png) ![image-20240129155110255](https://sse-market-source-1320172928.cos.ap-guangzhou.myqcloud.com/blog/image-20240129155110255.png) ### pytorch `pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121` `--index-url`是换源用的。为了方便后面进行环境配置,可以为pip配置清华源:`pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple` ### transformers transformers的安装比较简单,对于pip包管理器: `pip install transformers` ## 代码 增加测试过程中的记录。 ```python # 创建一个DataFrame用于存储结果 df = pd.DataFrame({'URL': nl_urls, 'Rank': ranks}) # 将结果保存到CSV文件 df.to_csv('evaluation_results.csv', index=False) ``` nl_urls是对应代码片段的序号,实际上**这个的输出和测试样本的顺序是一致的**。对于同一个代码会有多个不同的查询,所以nl_urls会重复。 分值越大说明模型在这个测试样本上效果越好。最好是1,最差是0.