用chatglm实现code interpreter

背景

开始文章之前可以先介绍下何为code interpreter。所谓code interpreter从实际操作讲就是让llm模型具备了立马执行代码、并把执行结果作为下轮模型生成的物料。这里面有两个关键词“立马执行代码”、“结果作为物料”,其实如果llm不具备控制计算机得到执行结果,并把生成的执行结果作为下一轮控制的物料,而只是能够生成静态的代码,那么llm不过还是一个静态的语言生成模型。但如果llm可以把生成的代码执行得到结果,那llm就是一个控制器和仿真器,根据需要生成代码动态的串接、补充需要的物料,以及对可能的选择做预测推断,让llm的能力直接无限制的扩张;这就是code interpreter的价值所在,让llm具备动态的自组装、调整可能组合、对决策做精准和模糊的仿真预测的能力。也就是说llm具备了解决实际问题的能力,而不是只能形而上的思考给出一些指导理论文案,而是可以切身的去尝试,从形而上到形而下的具体落地动作完全打通。

这也就是为什么code interpreter只是增加一个把生成代码可执行,这么一个看起来不太大的变化,让各大佬为之欢呼的原因。当然以现在的llm根据语言生成code的能力和code执行通过率(环境该有包没有),离稳健的商用系统还是有距离的。当然这些能力的提升事需要llm全面提升,甚至需要构建一个系统来解决的;这个一定事需要时间来沉淀和打磨,当然这也是机会所在。

例子:

1.图生成,传入原始图,指令生成抠人像的code,code interpreter处理结果,然后在对图像做image2image生成或者补背景;生成图在做线稿生成

2.文本生成,llm生成的文本有不合规多标点符号共现,指令生成正则处理code,code interpreter处理结果,然后在做下一步的文本抽摘要,或者文本改写

3.文本和图结合,生成文本和图做相似度计算,不合适让llm操控图继续生成,知道符合预期为止,甚至可以对前后生成图做风格判断,保证前后风格一致

技术点

要实现能够把生成的代码立刻执行的能力,就需要llm具备把生成代码做解释、编译、转成机器码执行。然后代码的编译、执行其实每种语言都是有编译器和执行器的,如果我们可以把代码发到对应语言的编译器、执行器那么就可以把代码操控cpu计算结果。要实现这样的能力,至少有4种办法(以python语言举例):

1.利用python的exec方法,把这个python解释器起一个flask服务,llm生成的代码作为参数传到这个服务器,执行结果返回给llm服务器

2.利用python interpreter方法来实现,起一个服务器接llm生成code,执行完结果返回给llm服务器

3.把llm生成的code存成py文件,llm服务器python os执行code

4.用ipython作为python代码解释服务器,llm生成代码送过来执行结果返回llm服务器

exec方法

prog = '''# 导入需要的库
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns# 生成示例数据,假设是关于学生的成绩,年龄,性别等信息
df = pd.DataFrame({"name": ["Alice", "Bob", "Charlie", "David", "Eve"],"score": [90, 80, 70, 60, 50],"age": [18, 19, 20, 21, 22],"gender": ["F", "M", "M", "M", "F"]
})# 查看数据的基本信息,如行数,列数,数据类型,缺失值等
df.info()# 查看数据的统计描述,如均值,标准差,最大值,最小值等
df.describe()# 选择需要分析的列,假设是score, age, gender
cols = ["score", "age", "gender"]# 绘制直方图,查看每列的分布情况
df[cols].hist(figsize=(10, 8))
plt.show()# 绘制箱线图,查看每列的异常值情况
df[cols].boxplot(figsize=(10, 8))
plt.show()# 绘制散点图矩阵,查看每两列之间的相关性
sns.pairplot(df[cols])
plt.show()'''
c = exec(prog)

python interpreter方法

参考下面一篇文章即可

https://mp.weixin.qq.com/s/_6E_yZ6g2X28tT2WAHeT7Q

python执行py文件方法

# 所以可以通过os.system来执行py代码
import os
os.system('python file_name.py')

ipython调度python编译器

from jupyter_client import KernelManager
import re class JupyterNotebook:def __init__(self):self.km = KernelManager()self.km.start_kernel()self.kc = self.km.client()def clean_output(self,outputs):outputs_only_str = list()for i in outputs:if type(i)==dict:if ('text/plain' in list(i.keys())):outputs_only_str.append(i['text/plain'])elif type(i)==str:outputs_only_str.append(i)elif type(i) == list:error_msg = '\n'.join(i)error_msg = re.sub(r'\x1b\[.*?m', '', error_msg)outputs_only_str.append(error_msg)return '\n'.join(outputs_only_str).strip()def add_and_run(self, code_string):# Execute the code and get the execution countmsg_id = self.kc.execute(code_string)# Wait for and return the outputsoutputs = []error_flag = Falsewhile True:try:msg = self.kc.get_iopub_msg(timeout=10)msg_type = msg['header']['msg_type']content = msg['content']if msg_type == 'execute_result':outputs.append(content['data'])elif msg_type == 'stream':outputs.append(content['text'])elif msg_type == 'error':error_flag = Trueoutputs.append(content['traceback'])# If the execution state of the kernel is idle, it means the cell finished executingif msg_type == 'status' and content['execution_state'] == 'idle':breakexcept:break#print(outputs)return self.clean_output(outputs), error_flag

还可以jupyter_client做执行器,flask部署成服务的例子,可以参考:https://github.com/ricklamers/gpt-code-ui.git

LLM生成代码技术点

class BaseCodeInterpreter:def __init__(self):self.dialog = [{"role": "system", "content": CODE_INTERPRETER_SYSTEM_PROMPT,},#{"role": "user", "content": "How can I use BeautifulSoup to scrape a website and extract all the URLs on a page?"},#{"role": "assistant", "content": "I think I need to use beatifulsoup to find current korean president,"}]self.nb = JupyterNotebook()#把llm生成的code部分抽取出来@staticmethoddef extract_code_blocks(text : str):pattern = r'```(?:python\n)?(.*?)```' # Match optional 'python\n' but don't capture itcode_blocks = re.findall(pattern, text, re.DOTALL)return [block.strip() for block in code_blocks]@staticmethoddef parse_last_answer(text: str) -> str:return text.split(E_INST)[-1]#把llm生成的抽取的code塞到jupyter解释器执行,得到结果返回给用户def execute_code_and_return_output(self, code_str: str) -> str:outputs, error_flag = self.nb.add_and_run(code_str)return outputs, error_flag

llm模型把生成代码生成能力封装到进去,code interpreter能力就具备了,下面代码model_path换成chatglm、codegeex2-6b都行。

class LlamaCodeInterpreter(BaseCodeInterpreter):def __init__(self, model_path: str, load_in_8bit : bool = False, load_in_4bit : bool = False):#self.model = LlamaForCausalLM.from_pretrained(model_path, device_map="auto", load_in_4bit = load_in_4bit,load_in_8bit=load_in_8bit, torch_dtype=torch.float16,use_safetensors=True)#self.tokenizer = LlamaTokenizer.from_pretrained(model_path)self.tokenizer = AutoTokenizer.from_pretrained(model_path,trust_remote_code=True)self.model = AutoModel.from_pretrained(model_path,trust_remote_code=True).cuda()'''# Add special tokenspecial_tokens_dict = dict()if self.tokenizer.pad_token is None:special_tokens_dict["pad_token"] = DEFAULT_PAD_TOKENif self.tokenizer.eos_token is None:special_tokens_dict["eos_token"] = DEFAULT_EOS_TOKENif self.tokenizer.bos_token is None:special_tokens_dict["bos_token"] = DEFAULT_BOS_TOKENif self.tokenizer.unk_token is None:special_tokens_dict["unk_token"] = DEFAULT_UNK_TOKENsmart_tokenizer_and_embedding_resize(special_tokens_dict=special_tokens_dict,tokenizer=self.tokenizer,model=self.model,)'''self.dialog = [{"role": "system", "content": CODE_INTERPRETER_SYSTEM_PROMPT + "\nUse code to answer",},#{"role": "user", "content": "How can I use BeautifulSoup to scrape a website and extract all the URLs on a page?"},#{"role": "assistant", "content": "I think I need to use beatifulsoup to find current korean president,"}]self.nb = JupyterNotebook()def dialog_to_prompt(self, dialog: List[Dialog], SYS_PROMPT: str = '') -> torch.Tensor:"""code borrowed from : https://github.com/facebookresearch/llama/blob/main/llama/generation.py"""if dialog[0]["role"] != "system":dialog = [{"role": "system","content": SYS_PROMPT,}] + dialogdialog = [{"role": dialog[1]["role"],"content": B_SYS + dialog[0]["content"] + E_SYS + dialog[1]["content"],}] + dialog[2:]assert all([msg["role"] == "user" for msg in dialog[::2]]) and all([msg["role"] == "assistant" for msg in dialog[1::2]]), ("model only supports 'system', 'user' and 'assistant' roles, ""starting with 'system', then 'user' and alternating (u/a/u/a/u...)")#print(dialog[::2], dialog[1::2],)dialog_tokens: List[int] = sum([self.tokenizer.encode(f"{B_INST} {(prompt['content']).strip()} {E_INST} {(answer['content']).strip()} ",)for prompt, answer in zip(dialog[::2],dialog[1::2],)],[],)#assert (#    dialog[-1]["role"] == "user"#), f"Last message must be from user, got {dialog[-1]['role']}"dialog_tokens += self.tokenizer.encode(f"{B_INST} {(dialog[-1]['content']).strip()} {E_INST}",)return torch.tensor(dialog_tokens).unsqueeze(0)def hard_coded_eos_splitter(self):self.dialog[-1]['content'] = self.dialog[-1]['content'].split(DEFAULT_EOS_TOKEN)[0]def chat(self, user_message: str, VERBOSE :bool = False):self.dialog.append({"role": "user", "content": user_message})code_block_output = ""attempt = 0 img_data = Noneif VERBOSE:print('###User : ' + Fore.BLUE + Style.BRIGHT + user_message + Style.RESET_ALL)print('\n###Assistant : ')while True:if attempt > 3:breakdialog_tokens = self.dialog_to_prompt(dialog=self.dialog)gen_tokens = self.model.generate(dialog_tokens.cuda(),max_new_tokens=4096,top_p=0.8,temperature=0.95,do_sample=True,use_cache=True)generated_text_all = self.tokenizer.batch_decode(gen_tokens)[0]generated_text = self.tokenizer.batch_decode(gen_tokens[:, dialog_tokens.shape[1]:])[0]last_answer = self.parse_last_answer(generated_text_all)generated_code_blocks = self.extract_code_blocks(generated_text)if len(generated_code_blocks) > 0:# Find the position of the first code block in the last answerfirst_code_block_pos = generated_text.find(generated_code_blocks[0]) if generated_code_blocks else -1text_before_first_code_block = generated_text if first_code_block_pos == -1 else generated_text[:first_code_block_pos]if VERBOSE:print(Fore.GREEN + text_before_first_code_block + Style.RESET_ALL)if VERBOSE:print(Fore.YELLOW + generated_code_blocks[0]+ '\n```\n' + Style.RESET_ALL)code_block_output, error_flag = self.execute_code_and_return_output(generated_code_blocks[0])code_block_output = f'{code_block_output}'if code_block_output is not None:code_block_output = code_block_output.strip()code_block_output_str = f'\n```RESULTS\n{code_block_output}\n```\n'if VERBOSE:print(Fore.LIGHTBLACK_EX + code_block_output_str + Style.RESET_ALL)#markdown = Markdown(code_block_output_str)print(markdown)gen_final = f'{text_before_first_code_block}{generated_code_blocks[0]}\n```{code_block_output_str}'if self.dialog[-1]['role'] == 'user':self.dialog.append({"role": "assistant", "content": gen_final})elif self.dialog[-1]['role'] == 'assistant':self.dialog[-1]['content'] += gen_finalelse:if self.dialog[-1]['role'] == 'user':self.dialog.append({"role": "assistant", "content": generated_text})else:self.dialog[-1]['content'] += generated_text# no code found breakif VERBOSE:print(Fore.GREEN + generated_text + Style.RESET_ALL)break# early stop if DEFAULT_EOS_TOKEN in self.dialog[-1]['content']:self.hard_coded_eos_splitter()if img_data is not None:return f'{self.dialog[-1]}\n![plot](data:image/png;base64,{img_data})'return self.dialog[-1]self.hard_coded_eos_splitter()attempt += 1#print(f"====Attempt[{attempt}]====\n{self.dialog[-1]['content']}")#print(self.dialog)if img_data is not None:return f'{self.dialog[-1]}\n![plot](data:image/png;base64,{img_data})'return self.dialog[-1]

执行结果如下:

蓝色字部分是用户输入问题,黄色字部分是llm生成的code,灰色部分是python解释器对code执行生成的结果。

小结

1.文章从技术趋势的酵素介绍了code interpreter的价值和有意义的方向在何

2.介绍了code interpreter实现的核心问题,就是如何把llm生成的code,可以调器编译器执行

3.以python语言为例,列举了4种可行的code到代码执行的方法,并给出了具体的实现代码

4.介绍了如何把llm和代码解释器封装成代码到解释器执行结果的实现,并给出了代码

5.给出了一个整合好的项目实现,并给出了一个简单的冒泡排序实现例子

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/20152.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

图文演示:如何三分钟极速搭建一个元宇宙3D虚拟展厅

引言: 元宇宙3D虚拟展厅时代已经来临。元宇宙是一个虚拟的、立体的数字空间,可以让用户沉浸在其中进行交互操作,并体验无限可能。如何快速搭建一个属于自己的虚拟展厅则受到越来越多人的关注。 一.虚拟展厅类型 1.党建展馆 实现…

html:去除input/textarea标签的拼写检查

默认情况下&#xff0c;textarea 会启动拼写和语法检查&#xff0c;表现效果就是单词拼写错误会出现红色下划线提示 <textarea></textarea>效果 有时&#xff0c;我们并不需要拼写检查&#xff0c;可以通过配置属性spellcheck"false" 去除拼写和语法检…

振弦传感器信号转换器应用山体滑坡安全监测

振弦传感器信号转换器应用山体滑坡安全监测 随着人类文明的进步&#xff0c;自然灾害对人们的生活和财产安全造成的威胁也越来越大。山体滑坡作为自然灾害中的一种&#xff0c;给人们的生活和财产安全带来了极大的威胁。因此&#xff0c;进行山体滑坡的安全监测显得尤为重要。振…

【U8+】用友U8重新注册加密锁,提示:写卡失败,请重新配置客户端控件。

【问题描述】 用友U8软件重新安装后&#xff0c;需要重新注册加密锁激活软件。 注册反馈提示&#xff1a;产品注册失败。 原因&#xff08;1&#xff09;&#xff1a;写卡失败&#xff0c;请重新配置客户端控件。 【解决方法】 1、打开控制面板&#xff0c;网络和 Internet&a…

ArmSoM-W3之RK3588安装Qt+opencv+采集摄像头画面

1. 简介 场景&#xff1a;在RK3588上做qt开发工作 RK3588安装Qtopencv采集摄像头画面 2. 环境介绍 这里使用了OpenCV所带的库函数捕获摄像头的视频图像。 硬件环境&#xff1a; ArmSoM-RK3588开发板、&#xff08;MIPI-DSI&#xff09;摄像头 软件版本&#xff1a; OS&…

PSO粒子群优化算法

PSO粒子群优化算法 算法思想matlab代码python代码 算法思想 粒子群算法&#xff08;Particle Swarm Optimization&#xff09; 优点: 1&#xff09;原理比较简单&#xff0c;实现容易&#xff0c;参数少。 缺点: 1&#xff09;易早熟收敛至局部最优、迭代后期收敛速度慢的…

初阶数据结构——二叉树题目

文章目录 一、单值二叉树二、检查两颗树是否相同三、另一棵树的子树四、二叉树的前序遍历五、对称二叉树 一、单值二叉树 单值二叉树 如果二叉树每个节点都具有相同的值&#xff0c;那么该二叉树就是单值二叉树。只有给定的树是单值二叉树时&#xff0c;才返回 true&#xff…

swift - 如何在数组大小更改后刷新 ForEach 显示元素的数量(SwiftUI、Xcode 11 Beta 5)

我正在尝试实现一个 View &#xff0c;该 View 可以在内容数组的大小发生变化时更改显示项目的数量(由 ForEach 循环创建)&#xff0c;就像购物应用程序可能会在用户下拉刷新后更改其可用项目的数量一样 这是我到目前为止尝试过的一些代码。如果我没记错的话&#xff0c;这些适…

SQL Developer中的Active Data Guard

这篇文章 Display Data Guard configuration in SQL Developer 中&#xff0c;用SQL Developer展示了多种ADG的拓扑。 今天自己也试了一下&#xff0c;还蛮简单的&#xff0c;其实最麻烦的部分在于搭建一个ADG环境。 假设我已有一个ADG环境&#xff0c;即最典型的环境&#x…

软考 系统分析师和系统架构师 项目管理师

软考整起 https://www.ruankao.org.cn/ 什么是计算机技术与软件&#xff08;初级、中级、高级&#xff09;考试&#xff08;软考&#xff09;&#xff1f; - 知乎 系统分析师和系统架构师关系 这两年&#xff0c;我先后报考了计算机技术与软件专业技术资格&#xff08;水平&a…

恒运资本:满仓的含义?

满仓&#xff0c;望文生义&#xff0c;便是财经领域中的一个术语。它指的是出资者将一切可用资金悉数用于购买股票、基金或其他金融资产。满仓的意义是出资者对某种出资产品充满决心&#xff0c;并乐意将自己的大部分资金投入其中&#xff0c;以希望取得更高的报答。但是&#…

Python-ElasticSearch客户端的封装(聚合查询、统计查询、全量数据)

目录 ES Python客户端介绍封装代码测试代码参考 ES Python客户端介绍 官方提供了两个客户端elasticsearch、elasticsearch-dsl pip install elasticsearchpip install elasticsearch-dsl第二个是对第一个的封装&#xff0c;类似ORM操作数据库&#xff0c;可以.filter、.group…

线上通过Nginx部署前端工程,并且配置SSL

介绍、为了更好的帮助大家学习&#xff0c;减少歧义,IP地址我就不隐藏了&#xff0c;公司也是我自己的公司。你们就别来攻击了。 下面给出步骤: 一、前期准备工作 通过在目标服务器上安装宝塔面板、安装redis、mysql、nginx、jdk环境等 1、 2、前端工程通过npm run build 打…

MMDeploy安装、python API测试及C++推理

服务器配置如下&#xff1a; Cuda版本&#xff1a;11.1 Cudnn版本&#xff1a;8.2.0 显卡版本&#xff1a;RTX3090 使用转换脚本将.pth模型转换为ONNX格式 python mmdeploy/tools/deploy.py \mmdeploy/configs/mmdet/detection/detection_onnxruntime_dynamic.py \mmdetect…

go 语言实战入门案例之命令行排版词典

文章和代码已经归档至【Github仓库&#xff1a;https://github.com/timerring/backend-tutorial 】或者公众号【AIShareLab】回复 go 也可获取。 文章目录 命令行排版的词典生成 request body解析 response body打印结果结构完善 命令行排版的词典 先看一下用到的 API &#x…

【C++】STL——set和map及multiset和multiset的介绍及使用

&#x1f680; 作者简介&#xff1a;一名在后端领域学习&#xff0c;并渴望能够学有所成的追梦人。 &#x1f681; 个人主页&#xff1a;不 良 &#x1f525; 系列专栏&#xff1a;&#x1f6f8;C &#x1f6f9;Linux &#x1f4d5; 学习格言&#xff1a;博观而约取&#xff0…

kafka 理论知识

1 首先要了解kafka是什么 Kafka是一个分布式的消息订阅系统 1.1 kafka存储消息的过程 消息被持久化到一个topic中&#xff0c;topic是按照“主题名-分区”存储的&#xff0c;一个topic可以分为多个partition&#xff0c;在parition(分区)内的每条消息都有一个有序的id号&am…

wxwidgets Ribbon使用简单实例

// RibbonSample.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <wx/wx.h> #include "wx/wxprec.h" #include "wx/app.h" #include "wx/frame.h" #include "wx/textctrl.h" #include "…

大数据学习教程:Linux 高级教程(上)

一、Linux用户与权限 1. 用户和权限的基本概念 1.1、基本概念 用户 是Linux系统工作中重要的一环, 用户管理包括 用户 与 组 管理 在Linux系统中, 不论是由本级或是远程登录系统, 每个系统都必须拥有一个账号, 并且对于不同的系统资源拥有不同的使用权限 对 文件 / 目录 的…

[C++项目] Boost文档 站内搜索引擎(1): 项目背景介绍、相关技术栈、相关概念介绍...

项目背景 Boost库是C中一个非常重要的开源库. 它实现了许多C标准库中没有涉及的特性和功能, 一度成为了C标准库的拓展库. C新标准的内容, 很大一部分脱胎于Boost库中. Boost库的高质量代码 以及 提供了更多实用方便的C组件, 使得Boost库在C开发中会被高频使用 为方便开发者学…