山东天成水利建设有限公司网站,查权重网站,长春网站制作招聘信息,做网站安全认证引言 模型简介 依赖安装 模型inference 代码补全 4-bit版模型 代码填充 指令编码 Code Llama vs ChatGPT vs GPT4 小结
引言
青山隐隐水迢迢#xff0c;秋尽江南草未凋。 小伙伴们好#xff0c;我是《小窗幽记机器学习》的小编#xff1a;卖热干面的小女孩。紧接… 引言 模型简介 依赖安装 模型inference 代码补全 4-bit版模型 代码填充 指令编码 Code Llama vs ChatGPT vs GPT4 小结
引言
青山隐隐水迢迢秋尽江南草未凋。 小伙伴们好我是《小窗幽记机器学习》的小编卖热干面的小女孩。紧接前文
今天这篇小作文作为代码大语言模型Code Llama的下篇主要介绍如何在本地部署Code Llama同时介绍如何对Code Llama做模型量化。最后对比Code Llama、ChatGPT和GTP4这三者的代码生成效果。 模型简介
官方发布了3类Code Llama模型每类都有三种模型尺寸 Code LlamaBase模型(即常说的基座模型)为通用的代码生成和理解而设计。 Code Llama - Python专门为Python而设计。 Code Llama - Instruct遵循指令更加安全可以作为代码助手。
三者关系如下 依赖安装
pip3 install githttps://github.com/huggingface/transformers.gitmain accelerate -i https://mirrors.cloud.tencent.com/pypi/simpletransformers版本:Version: 4.33.0.dev0。
本文以下实验代码的获取请前往《小窗幽记机器学习》找小编获取。 模型inference
代码补全
测试代码补齐功能的代码如下
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Time : 2023/9/4 20:07
# Author : 卖秋裤的小女孩
# File : inference_code_llama_hf.py
# 联系方式 : 微信公众号小窗幽记机器学习from transformers import AutoTokenizer
import transformers
import torch测试代码补全能力model_path /home/model_zoo/LLM/llama2/CodeLlama-34b-Python-hf/
tokenizer AutoTokenizer.from_pretrained(model_path)
pipeline transformers.pipeline(text-generation,modelmodel_path,torch_dtypetorch.float16,device_mapauto,
)sequences pipeline(def fibonacci(,do_sampleTrue,temperature0.2,top_p0.9,num_return_sequences1,eos_token_idtokenizer.eos_token_id,max_length512,
)
for seq in sequences:print(fResult: {seq[generated_text]})
以上使用34B的模型做代码补齐能力测试如果将模型置于一张A100(40G)上做inference显存基本打满 经过「漫长」的等待终于「输出结果」
Result: def fibonacci(n):if n 0:return 0elif n 1:return 1else:return fibonacci(n-1) fibonacci(n-2)def fibonacci_iterative(n):if n 0:return 0elif n 1:return 1else:a 0b 1for i in range(2, n1):c a ba bb creturn bdef fibonacci_iterative_2(n):if n 0:return 0elif n 1:return 1else:a 0b 1for i in range(2, n1):c a ba bb creturn cdef fibonacci_iterative_3(n):if n 0:return 0elif n 1:return 1else:a 0b 1for i in range(2, n1):c a ba bb creturn adef fibonacci_iterative_4(n):if n 0:return 0elif n 1:return 1else:a 0b 1for i in range(2, n1):c a ba bb creturn adef fibonacci_iterative_5(n):if n 0:return 0elif n 1:return 1else:a 0b 1for i in range(2, n1):c a ba bb creturn a
如果用2张A100(40G)加载模型做inference能够相对较快返回结果。所以对于34B版模型建议先做量化再用多块A100的做inference。
4-bit版模型
Transformers中已集成Code Llama因此可以直接使用Transformers加载4-bit模型。这使得在消费级的nvidia 3090卡上运行大型的32B参数模型变得可能以下演示如何在4-bit模式下进行推理的方法
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Time : 2023/9/4 21:01
# Author : 卖秋裤的小女孩
# 联系方式 : 微信公众号小窗幽记机器学习
# File : inference_code_llama_34B_4bit.pyfrom transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig
import torchmodel_id /home/model_zoo/LLM/llama2/CodeLlama-34b-Python-hf/
# model_id codellama/CodeLlama-34b-hf
quantization_config BitsAndBytesConfig(load_in_4bitTrue,bnb_4bit_compute_dtypetorch.float16
)tokenizer AutoTokenizer.from_pretrained(model_id)
model AutoModelForCausalLM.from_pretrained(model_id,quantization_configquantization_config,device_mapauto,
)prompt def remove_non_ascii(s: str) - str:\n
inputs tokenizer(prompt, return_tensorspt).to(cuda)output model.generate(inputs[input_ids],max_new_tokens512,do_sampleTrue,top_p0.9,temperature0.1,
)
output output[0].to(cpu)
print(tokenizer.decode(output))inference期间显卡占用情况 「输出结果如下」
s def remove_non_ascii(s: str) - str:Remove non-ascii characters from a stringreturn .join(c for c in s if ord(c) 128)def clean_string(s: str) - str:Clean a string by removing non-ascii characters and then removingany extra whitespaces remove_non_ascii(s)s s.strip()return s
/s鉴于inference速度问题后续试验选用7B大小的模型。
代码填充
这是一个针对代码模型的特殊任务。在该任务下模型为现有前缀和后缀的代码包括注释生成最佳匹配的代码。这是代码助手通常使用的策略根据出现在光标前后的内容填充当前的光标位置的内容。这个任务只能在「7B和13B模型的基座模型和指令微调模型」中使用。代码填充任务「不适用于34B版模型或Python版模型」。如果想要使用代码填充功能需要注意训练模型的格式因为它使用特殊的分隔符来识别提示的不同部分。可以直接使用transformers的CodeLlamaTokenizer。在底层tokenizer会自动通过FILL_ME进行分割以创建一个符合原始训练模式的格式化输入字符串。具体代码如下
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Time : 2023/9/4 19:25
# Author : 卖秋裤的小女孩
# 联系方式 : 微信公众号小窗幽记机器学习
# File : inference_code_infilling_hf.pyfrom transformers import AutoTokenizer, AutoModelForCausalLM, AutoConfig
import torch# model_id /home/model_zoo/LLM/llama2/CodeLlama-7b-Python-hf # 代码填充任务不适用于Python版模型
model_id /home/model_zoo/LLM/llama2/CodeLlama-7b-Instruct-hf
tokenizer AutoTokenizer.from_pretrained(model_id)
model_config AutoConfig.from_pretrained(model_id)
model AutoModelForCausalLM.from_pretrained(model_id,configmodel_config,torch_dtypetorch.float16
).to(cuda)prompt def remove_non_ascii(s: str) - str: FILL_MEreturn result
input_ids tokenizer(prompt, return_tensorspt)[input_ids].to(cuda)
output model.generate(input_ids,max_new_tokens512,
)
output output[0].to(cpu)filling tokenizer.decode(output[input_ids.shape[1]:], skip_special_tokensTrue)
print(prompt.replace(FILL_ME, filling))输出结果如下
def remove_non_ascii(s: str) - str: Remove non-ASCII characters from a string. Args: s (str): The string to remove non-ASCII characters from. Returns: str: The string with non-ASCII characters removed. result for c in s: if ord(c) 128: result c return resultdef remove_non_ascii_and_spaces(s: str) - str: Remove non-ASCII and space characters from a string. Args: s (str): The string to remove non-ASCII and space characters from. Returns: str: The string with non-ASCII and space characters removed. result for c in s: if ord(c) 128 and c ! : result c return resultdef remove_non_ascii_and_spaces_and_newlines(s: str) - str: Remove non-ASCII, space, and newline characters from a string. Args: s (str): The string to remove non-ASCII, space, and newline characters from. Returns: str: The string with non-ASCII, space, and newline characters removed. result for c in s: if ord(c) 128 and c not in [\n, \r, \t, ]: result c return resultdef remove_non_ascii_and_spaces_and_newlines_and_punctuation(s: str) - str: Remove non-ASCII, space, newline, and punctuation characters from a string. Args: s (str): The string to remove non-ASCII, space, newline, and punctuation characters from. Returns: str: The string with non-ASCII, space, newline, and punctuation characters removed. result for c in s: if ord(c) 128 and c not in [\ return result
如果在上述代码中强行使用CodeLlama-7b-Python-hf模型做代码填充任务模型inference的时候可能报错
RuntimeError: CUDA error: CUBLAS_STATUS_NOT_INITIALIZED when calling cublasCreate(handle)指令编码
如前面所述基座模型可以用于代码补全和填充Code Llama还发布了一个经过指令微调的模型可用于对话式编程。 针对这个任务需要使用llama2中的提示模板具体可以参考之前的文章Llama 2实战(上篇):本地部署(附代码)
s[INST] SYS
{{ system_prompt }}
/SYS{{ user_msg_1 }} [/INST] {{ model_answer_1 }} /ss[INST] {{ user_msg_2 }} [/INST]
注意系统提示是可选的在没有它的情况下模型可以正常工作但我们可以使用系统提示system_prompt来进一步配置模型的行为或风格。例如总是希望得到JavaScript的代码答案可以在这里指定。在系统提示之后需要提供历史对话用户询问的问题和模型的回答。与代码填充案例一样需要注意使用分隔符。输入的最后一个组成必须始终是一个新的用户指令这是模型提供答案的信号。以下代码片段演示了在实践中模板的工作方式。 没有system prompt的用户query
user I have a pandas DataFrame df[text], how can I directly add a list of data test_list to df[text] to increase the number of rows?prompt fs[INST] {user.strip()} [/INST]
inputs tokenizer(prompt, return_tensorspt, add_special_tokensFalse).to(cuda)
「完整示例代码」
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Time : 2023/9/5 20:49
# Author : 卖猪脚饭的小女孩
# 联系方式 : 微信公众号小窗幽记机器学习
# File : inference_code_instructions_hf_v2.py测试 instruction 版模型
CUDA_VISIBLE_DEVICES2 python3 inference_code_instructions_hf_v2.pyfrom transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfigmodel_id /home/model_zoo/LLM/llama2/CodeLlama-7b-Instruct-hf/
# model_id codellama/CodeLlama-34b-hf
# device_mapauto,
tokenizer AutoTokenizer.from_pretrained(model_id)
model AutoModelForCausalLM.from_pretrained(model_id,
).to(cuda)user_query I have a pandas DataFrame df[text], how can I directly add a list of data test_list to df[text] to increase the number of rows?prompt fs[INST] {user_query.strip()} [/INST]
inputs tokenizer(prompt, return_tensorspt).to(cuda)output model.generate(inputs[input_ids],max_new_tokens512,do_sampleTrue,top_p0.9,temperature0.1,
)
output output[0].to(cpu)
print(tokenizer.decode(output))输出结果如下
ss [INST] I have a pandas DataFrame df[text], how can I directly add a list of data test_list to df[text] to increase the number of rows? [/INST] You can use the append method to add a list of data to a pandas DataFrame. Heres an example:import pandas as pd# create a sample DataFramedf pd.DataFrame({text: [hello, world]})# create a list of data to addtest_list [foo, bar, baz]# add the list to the DataFramedf[text] df[text].append(test_list)print(df)This will output: text0 hello1 world2 foo3 bar4 bazNote that the append method returns a new DataFrame with the added data, so you need to assign the result back to the original DataFrame.Alternatively, you can use the concat function to concatenate the DataFrame with the list of data:import pandas as pd# create a sample DataFramedf pd.DataFrame({text: [hello, world]})# create a list of data to addtest_list [foo, bar, baz]# concatenate the DataFrame with the list of datadf pd.concat([df, pd.DataFrame({text: test_list})])print(df)This will output the same result as the previous example./s
可以看出输出了2种代码。 第一种
import pandas as pd# create a sample DataFrame
df pd.DataFrame({text: [hello, world]})# create a list of data to add
test_list [foo, bar, baz]# add the list to the DataFrame
df[text] df[text].append(test_list)print(df)第一种代码写法无法正常运行。
第二种
import pandas as pd# create a sample DataFrame
df pd.DataFrame({text: [hello, world]})# create a list of data to add
test_list [foo, bar, baz]# concatenate the DataFrame with the list of data
df pd.concat([df, pd.DataFrame({text: test_list})])print(df)经过测试第二种写法可以正常运行且结果符合预期。
所以简单的代码需求CodeLlama-7b-Instruct-hf表现一般可能存在一些比较明显的坑。
进一步尝试使用34B版模型CodeLlama-34b-Instruct-hf生成代码如下
import pandas as pd# create a sample DataFrame with a text column
df pd.DataFrame({text: [hello, world, this, is, a, test]})# create a list of data to add to the text column
test_list [new, data, to, add]# concatenate the text column with the test_list
df[text] pd.concat([df[text], test_list])print(df)上述代码直接运行会报错
TypeError: cannot concatenate object of type class list; only Series and DataFrame objs are valid带system prompt的用户query
system Provide answers in C
user Write a function that computes the set of sums of all contiguous sublists of a given list.prompt fsSYS\\n{system}\\n/SYS\\n\\n{user}
inputs tokenizer(prompt, return_tensorspt, add_special_tokensFalse).to(cuda) 带历史对话的持续对话
system System prompt
user_1 user_prompt_1
answer_1 answer_1
user_2 user_prompt_2
answer_2 answer_2
user_3 user_prompt_3prompt fSYS\\n{system}\\n/SYS\\n\\n{user_1}
prompt fs[INST] {prompt.strip()} [/INST] {answer_1.strip()} /s
prompt fs[INST] {user_2.strip()} [/INST] {answer_2.strip()} /s
prompt fs[INST] {user_3.strip()} [/INST]inputs tokenizer(prompt, return_tensorspt, add_special_tokensFalse).to(cuda)
ChatGPT vs GPT4
延续上述指令编程中的panda行方向数据扩增这一代码需求在ChatGPT和GPT4上对比测试。由于ChatGPT和GPT4都支持中文输入所以直接使用中文Promp输入
我有一个pandas数据 df[text]如何将一个list数据test_list直接添加到df[text]中使得行数变多「ChatGPT生成结果如下」
import pandas as pd# 原始数据
df pd.DataFrame({text: [hello, world]})# 要添加的数据
test_list [foo, bar]# 将test_list作为一个新的DataFrame对象添加到原始DataFrame对象中
new_df df.append(pd.DataFrame({text: test_list}), ignore_indexTrue)# 打印结果
print(new_df)ChatGPT生成代码运行结果如下 text
0 hello
1 world
2 foo
3 bar「GPT4生成结果如下」
# 假设这是你的原始DataFrame
import pandas as pd
df pd.DataFrame({text: [hello, world]})# 这是你要添加的list
test_list [foo, bar]# 将list转换为DataFrame
new_df pd.DataFrame({text: test_list})# 使用append方法将新的DataFrame添加到原来的DataFrame中
df df.append(new_df, ignore_indexTrue)print(df)GPT4生成代码运行结果如下 text
0 hello
1 world
2 foo
3 bar可以看出对于简单的代码需求ChatGPT和GPT4都cover住。
功能任务是否正常运行结果是否符合预期总体评估代码补全(34B版)求斐波那契数列yesyes代码补全(34B-4bit版)去除非ascii字符yesyes代码填充(7B-Instruct版)去除非ascii字符yesyes指令编程(7B-Instruct版)pandas指定列增加行数据yes noyes no指令编程(34B-Instruct版)pandas指定列增加行数据nonoChatGPTpandas指定列增加行数据yesyesGPT-4pandas指定列增加行数据yesyes
小结
在普通代码需求上现阶段的Code Llama模型仍然有一些明显的瑕疵实战效果仍不如ChatGPT和GPT4。相信Code Llama后续的发展及其成长可以进一步趋近当下的ChatGPT和GPT4。