头图

Falcon40b是当前最大的开源大语言模型之一,且采用商业友好的Apache 2.0许可证。这使得对于希望将NLP产品推向市场的开发者来说,它具有相当大的吸引力。

Falcon-40b-Instruct模型基于Falcon40b模型进行微调,用于指令接收和对话任务,在Hugging Face的LLM基准测试中名列前茅,仅次于基于Meta的非开源Llama系列的模型。Falcon40b的性能远优于其他开源模型。

作为最新一波开源大语言模型,Falcon系列模型受到Llama系列启发,核心思想是使用更多数据(在本例中超过一万亿代币)更长时间(更多时期)训练较小的模型。LLM相关的经验文献表明,模型规模、训练计算和训练数据集规模应该同步增加,但该模型系列使用的计算和训练数据远远超出预期。

使用CodeAlpaca进行微调

Falcon40b是一个预训练模型,但并未针对任何特定任务进行训练。它的零样本性能并不出色,需要通过训练才能用作聊天机器人或按照指令执行任务。
当我们希望它按照指令执行任务时,我们使用如Alpaca数据集的指令-响应对进行训练。
下面是来自Alpaca的一对指令-响应示例:

以下是一个描述任务的指令。请提供一个响应正确完成该请求。  

### 指令:
创建一个包含1到10之间所有偶数的长度为5的数组。  

### 响应:
arr = [2, 4, 6, 8, 10]  

Falcon-40b-Instruct模型已经被训练成一个通用的指令跟踪模型,因此我们决定不循规蹈矩。
最近,对训练大型语言模型来编写代码的兴趣越来越浓,这个领域有许多开源项目,特别是Starcoder、Replit3b、CodeGen和CodeGen2。因此,我们决定尝试使用CodeAlpaca数据集对Falcon40b进行微调,使其能够根据自然语言提示编写代码。

CodeAlpaca是一组包含20,000个指令-输入-代码三元组的数据集,与Alpaca数据集一样,它们是由闭源语言模型生成的。示例如下:

以下是一个描述任务的指令,与提供了更多上下文的输入配对。请提供一个响应,正确完成请求。  
### 指令:生成一段代码片段,提取给定字符串中的所有URL。  
### 输入:该字符串包含一些网址,如<https://www.google.com>和<https://www.facebook.com>。  
### 响应:import re  
string = "该字符串包含一些网址,如<https://www.google.com>和<https://www.facebook.com>。"urls = re.findall('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\\\\(\\\\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', string)print(urls)  

与通用指令跟踪任务相比,专用于代码构建训练Falcon40b在这些任务上表现更好。

微调超参数

我们使用LoRA进行微调,采用8位量化,使用了四个NVIDIA A100 Tensor Core GPU,每个GPU有80GB的VRAM。微调花费了约4小时,在runpod.io上花费了约25欧元。
我们使用了以下超参数:

  • Epochs:2
  • 添加LoRA的层:全注意层(QKV)
  • LoRA等级:8
  • 学习率:3.0e-4
  • Batch size:128

    💡我们注意到将epochs增加到2有助于模型“学习”何时停止。否则,它将重复指令模板,永不停止。  

    结果

    我们选择了45条编码指令,用于评估模型遵循指令的能力。经过微调,模型能够根据自然语言指令生成代码,回答关于代码段的问题,以及回答一般的计算机编程问题。
    例如:
    通用编程问题

    问题:
    解释Python中迭代器和生成器的区别并举例。  
    响应:
    迭代器是一种可用于遍历序列项(如列表或字符串)的对象。它提供了一种逐个访问序列中每个项的方法。生成器是一种可用于生成序列项(如列表或字符串)的函数。它提供了一种逐个生成序列中每个项的方法。迭代器和生成器的主要区别在于,迭代器是一种可用于遍历序列的对象,而生成器是一种可用于生成序列的函数。

根据自然语言提示生成代码

问题:
编写一个Python函数:接受一个单词列表,并返回一个字典,其中键是列表中的单词,值是列表中单词的频率。在解决方案中使用for循环、if条件和字典。
响应:
def word_frequency(words):
    frequencies = {}    
    for word in words:        
        if word in frequencies:            
            frequencies[word] += 1        
        else:            
            frequencies[word] = 1    
    return frequencies  

回答关于特定代码段的问题

问题:
解释以下Python脚本,该脚本使用FastAPI创建一个基本的'Hello World' API。  
from fastapi import FastAPI  

app = FastAPI()  

@app.get("/")
def read_root():    
    return {"Hello": "World"}  
响应:  
这个Python脚本使用FastAPI创建一个基本的'Hello World' API。FastAPI是一个能够轻松在Python中创建API的Web框架。@app.get("/")装饰器定义了API的路由,当访问该路由时将调用read_root()函数。该函数返回一个包含键"Hello"和值"World"的字典。 

编写处理AI模型的代码

问题:
编写一个使用transformers库对输入文本进行标记化并生成模型输出的Python脚本。  
响应:
import transformers

tokenizer = transformers.AutoTokenizer.from_pretrained("bert-base-uncased")
model = transformers.AutoModel.from_pretrained("bert-base-uncased")  

input_text = "This is an example text."  

tokenized_text = tokenizer.tokenize(input_text)model_output = model.generate(input_text)  

print(tokenized_text)
print(model_output)  

定量来看,使用了这个代码库进行评分,HumanEval基准测试的第一轮得分为22%。尽管这是一个不错的结果,但远没有达到专门用于编写代码的AI模型的最佳记录性能。

Falcon-40b-Instruct在相同任务上得分为18%。我们认为这是因为在更大数据集上的训练使其更好地遵循指令,即使它不擅长编写代码或解决编程问题。它的大部分知识似乎是在预训练阶段获得的。

简而言之

我们通过HuggingFace发布了两个模型:完整权重模型和我们微调的Falcon40b的LoRA适配器权重
尽管Falcon40b并非专门用于编码,但它在编码问题上表现出色。通过使用我们微调的LoRA掩码,您只需将少量额外的数据加载到内存中即可将任何Falcon40b安装转变为编码助手。

下载我们的代码并复现结果

您可以通过从GitHub查看我们的代码库并复现。代码包含对HuggingFace的transformers模块的透明封装。
首先,从GitHub获取我们的代码:

git clone <https://github.com/jina-ai/jerboa.git> 

然后,进入git库的根目录,并运行以下命令:

cd jerboa  
finetune.py --base-model tiiuae/falcon-40b --lora-target-modules query_key_value --data-path sahil2801/CodeAlpaca-20k --output-dir ./lora-alpaca-code --batch-size 128 --micro-batch-size 4 --eval-limit 45 --eval-file code_eval.jsonl --wandb-project jerboa --wandb-log-model --wandb-watch gradients --num-epochs 2

如果遇到问题,您可以恢复到我们在本文中使用版本的checkpoint:

git checkout abe1a23a4e9f5e141e19be0336ca8a4c888dd024  

您还可以尝试使用LLM Foundry或其他优化低训练成本的工具来减少计算和训练时间。

参与其中

访问Jina AI官网GitHub库Discord,探索人工智能能为您做些什么。


JinaAI
21 声望12 粉丝

Jina AI 的愿景是铺设通往多模态 AI 的未来之路,我们是您通往多模态人工智能的最佳通道!