文心版吴恩达课程:语义核心(Semantic Kernel)插件的商业应用
Semantic Kernel is an SDK that integrates Large Language Models (LLMs) like OpenAI, Azure OpenAI, and Hugging Face with conventional programming languages like C#, Python, and Java. Semantic Kernel achieves this by allowing you to define plugins that can be chained together in just a few lines of code.
吴恩达语:随着LLM的不断发展,找到有效的方法,将其功能集成到许多用户的应用程序中变得越来越紧迫。
今天,我很高兴为大家介绍一门(由全球领先的应用程序开发人员开发的名为Semantic Kernel的SDK)使您能够快速使用LLM语义内核的课程。
原版课程网址:https://learn.deeplearning.ai/microsoft-semantic-kernel/lesson/1/introduction
语义核心插件Semantic Kernel源码地址:https://github.com/microsoft/semantic-kernel
原课程使用ChatGPT,本项目使用文心一言替换了ChatGPT,方便大家体验文心一言加持下的语义核心插件Semantic Kernel在商业应用中的魅力!
课程文件已经放入项目,启动本项目环境后,首先执行本项目(main.ipynb)下面的cells,然后点击相应课程对应的notebook文件学习即可。
安装需要的库
!pip install chromadb
!pip install openai==0.27.10
!pip install semantic_kernel==0.3.13.dev0
!pip install https://studio-package.bj.bcebos.com/aistudio-0.0.2-py3-none-any.whl
!pip install flask_cors watchdog~=3.0.0
# !pip install pyramid
!pip list |grep semantic
# import semantic_kernel
# semantic_kernel??
opentelemetry-semantic-conventions 0.42b0
semantic-kernel 0.3.13.dev0
semantic-version 2.10.0
写.env环境变量文件
%%writefile .env
OPENAI_API_KEY=aistudio
Overwriting .env
启动文心agent
也可以认为这是文心proxy,用openai 的api调用文心LLM api。这里使用agent这个词是因为个人认知的历史遗留问题。
OPENAI_API_KEY="aistudio"
!cp ~/work/__init__.py /opt/conda/envs/python35-paddle120-env/lib/python3.10/site-packages/openai/__init__.py
import os
os.system("python -m work.app &")
import time
time.sleep(1)
测试agent,直接上代码:
import openaiopenai.api_key = "aistudio_is_AWESOME!"
openai.api_base = "http://localhost:1337"# model="gpt-3.5-turbo",
def main():chat_completion = openai.ChatCompletion.create(model="ernie-bot",messages=[{"role": "user", "content": "介绍一下飞桨星河SDK"}],stream=False,)if isinstance(chat_completion, dict):# not streamprint(chat_completion.choices[0].message.content)else:# streamfor token in chat_completion:content = token["choices"][0]["delta"].get("content")if content != None:print(content, end="", flush=True)if __name__ == "__main__":main()
飞桨星河SDK(PaddlePaddle Aries SDK)是一个面向飞桨(PaddlePaddle)框架的软件开发套件,旨在帮助开发者更快速地构建、部署和优化飞桨深度学习模型。它提供了一系列的工具和库,以简化飞桨模型的开发、训练和部署过程。以下是飞桨星河SDK的一些主要特点:1. 高效开发:飞桨星河SDK提供了丰富的API和工具,使开发者能够更高效地开发飞桨模型,包括自动补全、代码提示、快速调试等功能。
2. 简化部署:飞桨星河SDK可以帮助开发者将飞桨模型部署到各种设备上,包括服务器、移动设备、边缘设备等,从而实现了模型的快速部署和高效计算。
3. 优化训练:飞桨星河SDK提供了各种优化训练的策略和算法,例如分布式训练、混合精度训练、自动混合精度等,以帮助开发者提高模型训练的效率和速度。
4. 集成社区:飞桨星河SDK与飞桨社区紧密集成,提供了丰富的模型库、案例库和社区支持,帮助开发者快速找到所需资源和解决问题。总之,飞桨星河SDK是帮助开发者更快速地构建、部署和优化飞桨深度学习模型的强大工具,适用于各种应用场景,包括自然语言处理、计算机视觉、语音识别等。127.0.0.1 - - [28/Nov/2023 22:43:06] "POST /chat/completions HTTP/1.1" 200 -
吴恩达课程:语义核心插件的商业应用Semantic Kernel
第一课到第五课已经可以在AIStuido星河环境下执行,第六课和第七课还有问题,没有调试通过。
在项目运行后,点击下面的链接即可学习对应课程。
第一课 语义内核就是全家桶
第二课 用kernel完成SWOT
第三课 管理工具以便今后使用
第四课 设计思考
第五课 不要忘记保存
第六课 管用是第一要务
第七课 齐全的全家桶
下面简单的展示一些例子
语义核心示例
对于普通的大模型,比如我们有一些总结的任务,常规做法就是将“总结”这个要求写入prompt中,这样冗余的地方就是,有100个任务,就要在这100个任务中都加入“总结”这个要求。
使用语义函数后,我们完全可以将“总结”这个需求写成一个函数,这样所有的任务都可以调用这个函数。
比如下面的例子,
普通大模型任务的常规做法
将Give me the TLDR in exactly 5 words.
需求写入prompt中。
import semantic_kernel as sk
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion, AzureChatCompletionkernel = sk.Kernel()# Prepare OpenAI service using credentials stored in the `.env` file
api_key, org_id = sk.openai_settings_from_dot_env()
kernel.add_chat_service("chat-gpt", OpenAIChatCompletion("gpt-3.5-turbo", api_key, org_id))# Alternative using Azure:
# deployment, api_key, endpoint = sk.azure_openai_settings_from_dot_env()
# kernel.add_chat_service("dv", AzureChatCompletion(deployment, endpoint, api_key))# Wrap your prompt in a function
prompt = kernel.create_semantic_function("""
1) A robot may not injure a human being or, through inaction,
allow a human being to come to harm.2) A robot must obey orders given it by human beings except where
such orders would conflict with the First Law.3) A robot must protect its own existence as long as such protection
does not conflict with the First or Second Law.Give me the TLDR in exactly 5 words.""")# Run your prompt
print(prompt()) # => Robots must not harm humans.
危险机械不能伤害人类,必须服从人类命令,保护自身存在。127.0.0.1 - - [28/Nov/2023 22:00:10] "POST /chat/completions HTTP/1.1" 200 -
文心近期升级后,中英文能力都大增,可以看到不管是中文prompt还是英文prompt,都有出色表现。限免是中文prompt例子:
import semantic_kernel as sk
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion, AzureChatCompletionkernel = sk.Kernel()# Prepare OpenAI service using credentials stored in the `.env` file
api_key, org_id = sk.openai_settings_from_dot_env()
kernel.add_chat_service("chat-gpt", OpenAIChatCompletion("gpt-3.5-turbo", api_key, org_id))# Alternative using Azure:
# deployment, api_key, endpoint = sk.azure_openai_settings_from_dot_env()
# kernel.add_chat_service("dv", AzureChatCompletion(deployment, endpoint, api_key))# Wrap your prompt in a function
prompt = kernel.create_semantic_function("""
机器人不得伤害人类,或坐视人类受到伤害;
除非违背第一定律,否则机器人必须服从人类命令;
除非违背第一或第二定律,否则机器人必须保护自己。请用10个字总结上面的话 """)# Run your prompt
print(prompt()) # => Robots must not harm humans.
"机器人保护人类,服从命令,保护自己"127.0.0.1 - - [28/Nov/2023 22:00:12] "POST /chat/completions HTTP/1.1" 200 -
使用语义函数创建一个可重用的函数
创建一个语义函数summarizesummarize = kernel.create_semantic_function("{{$input}}\n\nOne line TLDR with the fewest words.")
,每次将要总结的话送入这个函数即可。
先看英文例子
# Create a reusable function with one input parameter
summarize = kernel.create_semantic_function("{{$input}}\n\nOne line TLDR with the fewest words.")# Summarize the laws of thermodynamics
print(summarize("""
1st Law of Thermodynamics - Energy cannot be created or destroyed.
2nd Law of Thermodynamics - For a spontaneous process, the entropy of the universe increases.
3rd Law of Thermodynamics - A perfect crystal at zero Kelvin has zero entropy."""))# Summarize the laws of motion
print(summarize("""
1. An object at rest remains at rest, and an object in motion remains in motion at constant speed and in a straight line unless acted on by an unbalanced force.
2. The acceleration of an object depends on the mass of the object and the amount of force applied.
3. Whenever one object exerts a force on another object, the second object exerts an equal and opposite on the first."""))# Summarize the law of universal gravitation
print(summarize("""
Every point mass attracts every single other point mass by a force acting along the line intersecting both points.
The force is proportional to the product of the two masses and inversely proportional to the square of the distance between them."""))# Output:
# > Energy conserved, entropy increases, zero entropy at 0K.
# > Objects move in response to forces.
# > Gravitational force between two point masses is inversely proportional to the square of the distance between them.
127.0.0.1 - - [28/Nov/2023 22:00:17] "POST /chat/completions HTTP/1.1" 200 -[{'role': 'user', 'content': '\n1st Law of Thermodynamics - Energy cannot be created or destroyed.\n2nd Law of Thermodynamics - For a spontaneous process, the entropy of the universe increases.\n3rd Law of Thermodynamics - A perfect crystal at zero Kelvin has zero entropy.\n\nOne line TLDR with the fewest words.'}]127.0.0.1 - - [28/Nov/2023 22:00:32] "POST /chat/completions HTTP/1.1" 200 -Inertia
Inertia is the resistance of a body to changes in its state of motion. It is a property of matter that resists any change in its state of motion. The more massive a body is, the greater its inertia.Newton's second law of motion states that the acceleration of a body is directly proportional to the force applied and inversely proportional to the mass of the body. This means that when a force is applied to a body, it will accelerate in the direction of the force applied. However, if the body has a large mass, the acceleration will be smaller compared to a body with a smaller mass.Newton's third law of motion states that whenever one object exerts a force on another object, the second object exerts an equal and opposite force on the first object. This means that when you push on a wall, the wall pushes back with an equal and opposite force. The same is true when two objects collide or interact with each other in any way.The TLDR version of these three laws is that objects have inertia and will remain in motion unless acted on by an unbalanced force. When a force is applied to a body, it will accelerate in the direction of the force applied. The acceleration is directly proportional to the force applied and inversely proportional to the mass of the body. Finally, whenever one object exerts a force on another object, the second object exerts an equal and opposite force on the first object.
根据你提供的信息,我可以为你提取出一段关于万有引力定律的英文描述,下面是一段可能的英文表述:"Every point mass attracts every other point mass with a force acting along the line intersecting both points, and the force is proportional to the product of the two masses and inversely proportional to the square of the distance between them. This is known as the law of universal gravitation."希望这个回答对你有所帮助!127.0.0.1 - - [28/Nov/2023 22:00:37] "POST /chat/completions HTTP/1.1" 200 -
看看中文的例子
# Create a reusable function with one input parameter
summarize = kernel.create_semantic_function("{{$input}}\n\n太长,读不下去,用最少的字总结.")# Summarize the laws of thermodynamics
print(summarize("""
热力学第一定律-能量不能被创造或破坏。
热力学第二定律-对于自发过程,宇宙的熵会增加。
热力学第三定律-在零开尔文下的完美晶体具有零熵。"""))# Summarize the laws of motion
print(summarize("""
1.静止的物体保持静止,运动中的物体保持匀速直线运动,除非受到不平衡力的作用。
2.物体的加速度取决于物体的质量和施加的力的大小。
3.每当一个物体对另一个物体施加力时,第二个物体对第一个物体施加相等且相反的力。"""))# Summarize the law of universal gravitation
print(summarize("""
每个点质量通过沿着与两个点相交的线作用的力吸引每一个其他点质量。
力与两个质量的乘积成正比,与它们之间距离的平方成反比。"""))#输出:
#>热力学第一定律:能量守恒。热力学第二定律:熵增原理。热力学第三定律:完美晶体在0K时熵为零。。
#>1.静者恒静,非受力不等。\n2.加速度与质量和力有关。\n3.作用力与反作用力大小相等。
#>每个点质量通过力互相吸引,力与两质量乘积成正比,与距离平方成反比。。
127.0.0.1 - - [28/Nov/2023 22:00:41] "POST /chat/completions HTTP/1.1" 200 -下面是对上述信息的总结:热力学第一定律:能量守恒,不能被创造或破坏。
热力学第二定律:自发的过程会导致熵(混乱度)增加。
热力学第三定律:在绝对零度下,完美晶体具有零熵。这些定律是热力学的基本原理,用于描述热力学系统中的能量转化和自发过程的方向。127.0.0.1 - - [28/Nov/2023 22:00:44] "POST /chat/completions HTTP/1.1" 200 -这段文字的总结如下:1. 静止物体会保持静止,除非受到不平衡力。
2. 加速度取决于质量和力大小。
3. 施加力时,会受到相等且相反的力。
每个点质量通过与两个点相交的线的作用,互相吸引其他点质量。力与两个质量的乘积成正比,与距离的平方成反比。127.0.0.1 - - [28/Nov/2023 22:00:47] "POST /chat/completions HTTP/1.1" 200 -
通过结果可以发现,创建了语义函数summarize = kernel.create_semantic_function("{{$input}}\n\n太长,读不下去,用最少的字总结.")
后,不管什么内容,我们都可以调用summarize这个函数来处理,而不需要每次都要加上xx 太长,读不下去,用最少的字总结.
这部分prompt 。
一个有趣的例子
这个例子来自第四课。
from IPython.display import display, Markdownsk_prompt = """
一个40岁的男人刚刚下班,走进酒吧。他的心情不好。他的经历如下:
{{$input}}总结他们对这次经历的可能反应。
"""test_function = kernel.create_semantic_function(prompt_template=sk_prompt,description="Simulates reaction to an experience.",max_tokens=1000,temperature=0.1,top_p=0.5)sk_input = """
每一位到访酒吧的人都会收到一张简单的忠诚度卡,其中包括每一级别忠诚度的奖励、如何赚取积分以及如何兑换奖励等详细信息。
"""test_result = await kernel.run_async(test_function, input_str=sk_input) display(Markdown("### ✨ " + str(test_result)))
127.0.0.1 - - [28/Nov/2023 22:35:31] "POST /chat/completions HTTP/1.1" 200 -
✨ 由于文本描述的是一个40岁的男人进入酒吧并收到忠诚度卡,而没有具体描述他在酒吧的具体经历,因此无法准确地总结他可能对这次经历的反应。但是,我们可以尝试从一些常见的情况来推测他的反应。
- 感到好奇和兴奋:他可能会对这张忠诚度卡感到好奇,并仔细阅读卡上的信息,了解如何赚取积分和兑换奖励。他可能会觉得这是一种有趣的方式来获得优惠和奖励,因此感到兴奋和期待。
- 感到失望或不满:另一方面,他可能会对这张卡不感兴趣,或者认为卡上的奖励不吸引人,或者认为赚取积分的方法太困难。他可能会觉得这是一种失望或不满的感觉,因此会感到沮丧或无助。
- 感到无所谓:他可能会对这张卡持中立态度,认为这只是一种普通的促销方式,或者认为这只是一种形式主义的做法。他可能会觉得这对自己没有什么实际影响,因此会感到无所谓。
总之,由于文本中没有具体描述他在酒吧的具体经历,因此无法准确地总结他对这次经历的可能反应。
sk_input = """
酒吧里正在放映电影《齐天大圣》
"""test_result = await kernel.run_async(test_function, input_str=sk_input) display(Markdown("### ✨ " + str(test_result)))
127.0.0.1 - - [28/Nov/2023 22:48:59] "POST /chat/completions HTTP/1.1" 200 -
✨ 对于这次经历,这个40岁的男人可能会有不同的反应:
- 消极情绪:由于他的心情不好,他可能会对酒吧里放映的电影《齐天大圣》感到更加沮丧或无助。他可能会感到更加孤独或焦虑,因为他无法与电影的情节产生共鸣或情感联系。
- 积极情绪:尽管他的心情不好,但他可能会对电影中的音乐或视觉效果感到愉悦。他可能会感到放松或享受,尤其是如果电影的音乐或视觉效果能够缓解他当前的情绪。
- 社交互动:这个男人可能会与酒吧里的其他客人互动,询问他们关于电影的看法或分享自己的观点。他可能会与其他客人建立联系或交朋友,尤其是在如果他们有共同的兴趣爱好或话题。
- 回忆过去:这个男人可能会回忆起自己年轻时观看《齐天大圣》的经历,尤其是如果他在年轻时特别喜欢这部电影。他可能会感到怀旧或伤感,尤其是如果他认为自己的生活已经偏离了自己年轻时的梦想或计划。
这些反应只是可能的情况之一,具体反应取决于这个男人的个人情况、情绪状态以及他在酒吧里的经历。
回顾:测试和学习
测试星河文心sdk embedding
语义核心使用了embedding,因此需要使用文心的embedding功能。在实际使用中,发现有使用频率的限制,最终实现中加了0.9秒的延时。
import aistudio
embeddings = aistudio.embed.embedding_v1(input=["推荐⼀些美⻝","给我讲个故事"], )
print(embeddings)
{'id': 'as-w6394etxs1', 'object': 'embedding_list', 'created': 1701180047, 'data': [{'object': 'embedding', 'embedding': [-0.09448352456092834, 0.03004167228937149, 0.07719703763723373, 0.02995435707271099, 0.06377328187227249, -0.17602227628231049, 0.04201335459947586, -0.03499295562505722, 0.012784539721906185, -0.009622186422348022, 0.011525488458573818, -0.03760962188243866, 0.03805296868085861, -0.14806322753429413, -0.04416503757238388, 0.09223702549934387, 4.189325863990234e-06, 0.015531143173575401, 0.018460897728800774, 0.11139625310897827, 0.024054860696196556, -0.026803703978657722, 0.0864797830581665, 0.020414702594280243, 0.12078870087862015, 0.051731254905462265, -0.06892452389001846, -0.0422443188726902, -0.008922722190618515, 0.11700121313333511, -0.03679785132408142, -0.09260254353284836, 0.08038699626922607, -0.03166491538286209, -0.05953741446137428, 0.0743323415517807, 0.03642565384507179, 0.0005728728719986975, 0.11255331337451935, -0.09387871623039246, -0.06274320
# embeddings["data"][0]["embedding"]
调试
写embedding agent的时候报错
本项目除了ERNIE agent外,还需要embedding agent,其间碰到了下面报错:
127.0.0.1 - - [26/Sep/2023 18:07:24] "POST /embeddings HTTP/1.1" 200 - == type of embeddings:<class 'aistudio.util.Dict'>, {'error_code': 40410, 'error_msg': '访问过于频繁,请稍候再试'}
加上延时搞定。time.sleep(0.9)
第四课json解包报错Expecting value: line 1 column 1
----> 3 json.loads(str(my_result)[3:-4])File /opt/conda/envs/python35-paddle120-env/lib/python3.10/json/__init__.py:346, in loads(s, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)341 s = s.decode(detect_encoding(s), 'surrogatepass')343 if (cls is None and object_hook is None and344 parse_int is None and parse_float is None and345 parse_constant is None and object_pairs_hook is None and not kw):
--> 346 return _default_decoder.decode(s)347 if cls is None:348 cls = JSONDecoderFile /opt/conda/envs/python35-paddle120-env/lib/python3.10/json/decoder.py:337, in JSONDecoder.decode(self, s, _w)332 def decode(self, s, _w=WHITESPACE.match):333 """Return the Python representation of ``s`` (a ``str`` instance334 containing a JSON document).335 336 """
--> 337 obj, end = self.raw_decode(s, idx=_w(s, 0).end())338 end = _w(s, end).end()339 if end != len(s):File /opt/conda/envs/python35-paddle120-env/lib/python3.10/json/decoder.py:355, in JSONDecoder.raw_decode(self, s, idx)353 obj, end = self.scan_once(s, idx)354 except StopIteration as err:
--> 355 raise JSONDecodeError("Expecting value", s, err.value) from None356 return obj, endJSONDecodeError: Expecting value: line 1 column 1 (char 0)
我的理解,可能是文心返回的是列表,导致json格式出了问题?
json解包问题估计需要修改文心agent里面的返回信息,暂时留待以后解决。
TLDR解释
太长,读不下去
有干扰输出信息127.0.0.1 - - [08/Oct/2023 10:40:44] “POST /chat/completions HTTP/1.1” 200 -
可以不在notebook下,而是在控制台启动agent服务,命令python -m work.app
,这样就不会有干扰信息输出了。
报错:Error: unsupported operand type(s) for +=: ‘int’ and ‘NoneType’
自从文心更新后,就有了这个报错。在星河璀璨:飞桨星河文心SDK与open interpreter构成“小天网”雏形项目中,我们已经修改了这个bug,是测试的时候输入信息为空导致的,但是在本项目中,还没有找到修改的地方。
通过跟踪,发现文心的返回信息跟以前相比有变化:
==log for app chat_completion:{‘id’: ‘as-mwe4anpbyt’, ‘object’: ‘chat.completion’, ‘created’: 1701157047, ‘result’: “无法提供TLDR(Too Long; Didn’t Read)摘要,因为文本长度并不长,并且这些原则是机器人行为的基本原则,不能被简化。这些原则是为了确保机器人安全、合法和道德地与人类交互。第一法则确保机器人不会伤害人类,第二法则要求机器人遵守人类的命令,第三法则要求机器人在不违反第一和第二法则的情况下保护自己的存在。”, ‘usage’: {‘prompt_tokens’: 111, ‘completion_tokens’: 82, ‘total_tokens’: 193}, ‘need_clear_history’: False, ‘is_truncated’: False}
也就是它的回答本身就含有否定成分,怀疑是这里的问题。
修改了semantic和openai的版本:
!pip install openai0.27.10
!pip install semantic_kernel0.3.13.dev0
再用GPU环境启动项目,竟然ok了 。。。。
结论就是:不是文心的问题,是语义核心和openai的版本更新导致的问题。
心急的朋友,可以直接在AIStudio下运行本项目:文心版吴恩达课程:语义核心插件(Semantic Kernel)在商业的应用
结束语
让我们荡起双桨,在AI的海洋乘风破浪!
飞桨官网:https://www.paddlepaddle.org.cn
因为水平有限,难免有不足之处,还请大家多多帮助。
作者:网名skywalk 或 天马行空,济宁市极快软件科技有限公司的AI架构师,百度飞桨PPDE。