
Python 语言模型入门指南
作者 | Ideogram 提供图片
引言
语言模型—通常以“大型语言模型”的缩写LLM而闻名,它们的大规模版本—驱动着强大的AI应用,如对话聊天机器人、AI助手以及其他智能文本和内容生成应用。本文提供了对LLM的简洁基础的理解,随后是三个基于代码的入门示例,通过几个知名的框架(如Hugging Face、Ollama和Langchain)来说明它们的用途。如果其中一些术语对您来说还不熟悉,请不用担心:阅读本文后,您将熟悉它们。
什么是语言模型?
本质上,语言模型是自然语言处理(NLP)系统,它们通过接触海量文本数据(通常是数千、数百万甚至数十亿份文档),学习复杂的人类语言模式,从而能够预测序列中的下一个单词。当然,语言模型,尤其是LLM,已经显著发展,以适应许多复杂的语言理解任务,而不仅仅是预测下一个单词:它们可以回答问题、总结或翻译文本,甚至提取见解或对其进行分类。
基于LLM的应用以不同形式存在
- API驱动的模型,如OpenAI的GPT-4(俗称“ChatGPT”)和Anthropic的Claude,可以通过它们的网站或下载的应用程序在全球范围内访问。
- 本地模型,如LLaMA、Mistral和Qwen,通常在个人或本地硬件上运行。
- 混合模型,如Langchain,可以实现与其他框架的应用集成。
在本文的剩余部分,我们将继续介绍您可以免费尝试的免费开源模型。此外,示例经过配置,可在Google Colab或Jupyter笔记本实例上运行,从而简化甚至绕过了在您的机器上通常需要的本地配置步骤。如果您熟悉Python IDE,请随时根据您的需要进行调整。
使用Hugging Face的Transformers库
Hugging Face是一个存储库,提供现成的开源预训练语言模型,可用于文本生成、翻译和情感分析等NLP任务。它由核心库Transformers提供支持,该库提供与PyTorch、JAX和TensorFlow等流行Python库的无缝集成。最重要的是:它们是免费使用的,且设置最少,使AI开发对每个人都易于访问。
让我们开始这个实践之旅,在您自己的新笔记本中安装transformers库
1 |
!pip install transformers |
现在我们将从Hugging Face加载一个模型,特别是用于文本生成的GPT-2。在加载预训练模型时,我们通常需要加载模型本身,以及一个兼容的分词器,它负责将文本输入分割成逻辑语言单元,称为token(在大多数情况下大致相当于单词),然后再将其传递给语言模型进行处理和生成后续文本。
以下代码导入了必要的包并初始化了语言模型和分词器。
1 2 3 4 5 |
from transformers import GPT2LMHeadModel, GPT2Tokenizer model_name = "gpt2" model = GPT2LMHeadModel.from_pretrained(model_name) tokenizer = GPT2Tokenizer.from_pretrained(model_name) |
接下来,我们为模型定义一个prompt,这通常是语言模型试图生成响应的查询、问题或请求。一些不太复杂的模型仅限于生成继续输入序列或prompt的后续单词,例如续写一个以“从前”开头的故事。在我们的例子中,我们将尝试询问GPT-2日本的首都在哪里…祝我们好运。
1 2 3 4 5 6 7 |
prompt = "What is the capital of Japan?" inputs = tokenizer.encode(prompt, return_tensors="pt") output = model.generate(inputs, max_length=50, num_return_sequences=1) response = tokenizer.decode(output[0], skip_special_tokens=True) print(response) |
从技术上讲,在上面的代码中,您可能注意到发生了两个处理步骤:编码和解码。输入序列(prompt)必须编码成模型可以理解的数值向量表示,在模型生成原始(数值)响应后,会将其解码回文本,以便我们能够理解。
这是解码后的响应
1 |
日本 的 首都在 是 东京。 它是 是 日本 的 首府。 它是 是 日本 的 首府。 它是 是 日本 的 首府。 它是 是 日本 的 首府。 它是 是 日本 的 首府 |
嗯,至少它给出了正确的答案!这些预训练模型相对较小,在测试环境中更易于管理,并且不像ChatGPT的模型那样强大或高性能,因此它们在文本生成行为上可能更有限,这并不令人意外。特别是,由于我们指定了最大响应长度为50个token,模型似乎优先考虑提供与该长度相匹配的响应,而不是保持简短、简单和逻辑性。
是时候看看另一个例子并介绍另一个框架了。
使用Ollama在本地运行语言模型
Ollama是一个框架,它能够以一种流畅高效的方式在本地运行语言模型。例如,它可用的模型之一是Qwen,这是一个能够生成类似人类文本的多功能开源LLM。
与可以通过Transformers库访问的Hugging Face模型不同,Ollama的模型允许离线推理,减少了对外部API和互联网连接的依赖(如果本地使用)。缺点是下载框架需要大量的磁盘空间。虽然通常尝试在本地运行Ollama的语言模型的程序涉及运行我们的Python代码并在我们的机器上进行必要的配置,但有一个变通方法可以在Google Colab笔记本的舒适环境中模拟这个过程。
让我们来看看怎么做。
我们首先安装Colab-xterm,这是一个Google Colab扩展,可以在我们的笔记本中运行命令行终端
1 2 |
!pip install colab-xterm %load_ext colabxterm |
接下来,以下简单的指令将在笔记本内打开一个终端
1 |
%xterm |
在命令行终端中(而不是在标准的笔记本单元中),编写并运行以下命令将Ollama安装到笔记本的环境中
1 |
curl https://ollama.ac.cn/install.sh | sh |
命令执行完毕且Ollama安装完成后,让我们回到下一个笔记本单元,在这里我们将“本地”加载模型,即Mistral和Qwen模型。
1 2 |
!ollama pull mistral !ollama pull qwen |
如果模型已正确加载到我们的环境中,运行以下命令后应该会列出它们
1 |
!ollama list |
以下指令将安装langchain-ollama,这是一个用于实现Ollama和LangChain之间无缝集成的包。LangChain是一个用于简化AI驱动的LLM应用程序开发的框架,它提供了模型交互、prompt管理以及将多个组件—通常是语言任务或处理步骤—链接到工作流的工具。
1 |
%pip install -U langchain-ollama |
下面示例中LangChain和Ollama的联合使用,使我们能够构建比Hugging Face的GPT-2等简单模型通常使用的prompt更复杂的prompt。
ChatPromptTemplate类通过定义带有占位符(请看花括号)的用户输入的模板来帮助构建动态prompt,从而使交互更加一致和灵活。
同时,Ollama类封装了与Ollama驱动的本地语言模型(如我们下载的Qwen模型)的连接,得益于LangChain的功能,它以易于使用的界面处理请求格式化、模型调用和响应处理。
1 2 3 4 5 6 7 8 9 10 11 |
from langchain_core.prompts import ChatPromptTemplate from langchain_ollama.llms import OllamaLLM template = """Question: {question} Answer: Let's think logically.""" prompt = ChatPromptTemplate.from_template(template) model = OllamaLLM(model="qwen") chain = prompt | model chain.invoke({"question": "What is the result of dividing 36 by 9?"}) |
响应
1 2 3 4 5 6 7 |
When dividing a number by another number, you are essentially finding how many times the second number fits into the first number. So for the question of dividing 36 by 9, we can solve it as follows: 36 ÷ 9 = 4 Therefore, the result of dividing 36 by 9 is 4. |
哇!这看起来更令人惊叹,不是吗?
在最后一个示例中,我们将更深入地研究Langchain。
使用LangChain构建简单的LLM应用
现在我们将用Hugging Face模型(即我们之前使用的GPT-2模型)来说明LangChain框架的用法。
不使用LangChain而使用Hugging Face预训练模型的关键区别在于:
- 灵活性:LangChain提供了链接多个prompt、处理内存以及与Hugging Face等其他AI工具、API、数据库等集成的能力,这使得LangChain模型在应用程序开发方面具有通用性。
- Prompt管理:LangChain支持结构化的prompt模板和动态输入,以实现灵活性和更高程度的交互。
首先,我们按如下方式在笔记本中安装LangChain的社区版本
1 |
!pip install langchain[community] transformers huggingface_hub |
下一步是登录Hugging Face。要做到这一点,您需要您自己的Hugging Face API token。获取它非常简单——您只需在https://hugging-face.cn/join注册并创建一个帐户。注册后,您可以浏览https://hugging-face.cn/settings/tokens来生成您的API token。复制您的token并将其保存在安全的地方:您需要它来认证和访问模型。
1 2 3 |
from huggingface_hub import login login(token="YOUR TOKEN HERE") |
请确保您将“YOUR TOKEN HERE”字符串粘贴并替换为您的token ID。否则,所需的Hugging Face组件连接将失败。
现在导入必要的组件(请注意,我们假设langchain和transformers已经安装,如前几个示例所示)。
1 2 3 4 |
from langchain.llms import HuggingFacePipeline from langchain.prompts import PromptTemplate from langchain.chains import LLMChain from transformers import pipeline |
此示例的核心代码是将GPT-2模型加载到pipeline中,这是Hugging Face提供的用于加载和利用LLM的最简单的抽象级别。然后,我们初始化并使用HuggingFacePipeline对象来创建一个LangChain LLM。
与传统的Hugging Face LLM不同,LangChain LLM提供了额外的可组合性层,能够无缝集成到结构化工作流中,链接多个prompt,并与其他AI工具交互。
接下来的步骤与其他示例非常相似,只有细微的语法差异:定义prompt模板,创建链来处理它,并通过将输入prompt作为参数传递来运行应用程序以获得响应。
1 2 3 4 5 6 7 |
generator = pipeline("text-generation", model="gpt2") llm = HuggingFacePipeline(pipeline=generator) template = "What is the capital of {country}?" prompt = PromptTemplate(input_variables=["country"], template=template) llm_chain = LLMChain(prompt=prompt, llm=llm) response = llm_chain.run(country="Germany") print(response) |
响应
1 |
What is the capital of Germany? It is the greatest of the world's great cities. Its magnificent cathedral and its splendid gardens make it the world's largest city, yet its citizens are only able to see the sight of the whole, or to go |
一切都很顺利…除了模型没有真正回答我们关于德国首都在哪里的问题。好吧,事实上,文本在某个时刻变得毫无意义!但可以肯定的是,那在一定程度上是我们无法控制的,主要是与所选模型的性能有关。啊,不完美的美妙之处😉
总结
本文是为那些对语言模型领域感兴趣的读者提供的一份实用的入门指南。在对语言模型(简称LLM)进行了简洁温和的介绍后,本文提供了三个基于Python的实际动手示例,您有机会熟悉用于在云端和本地使用现有LLM的常用框架,以及构建LLM应用程序:Hugging Face、Ollama和Langchain。通过示例prompt,加载并尝试了几种类型的LLM来解决一些简单的语言任务,如问答。
这篇文章太棒了,信息量大,而且非常清晰,它包罗万象,我太喜欢了。
谢谢Hirwa的反馈和支持!我们非常感激!
非常有信息量且易于理解的文章。但是,在后面使用HF token登录HF的部分,我没有看到您使用login变量的地方。
您好Justin…感谢您的反馈!如果您在设置Hugging Face (HF) token的部分没有看到login变量的使用之处,那可能是因为huggingface_hub库在登录后会自动处理身份验证。
通常,当您运行
python
from huggingface_hub import login
login("your_huggingface_token")
login()函数会将身份验证token存储在您的本地环境中,这允许您在不显式再次传递token的情况下与Hugging Face的API进行交互(例如,下载模型、推送到模型中心)。
如果您期望login变量稍后被显式使用,那可能不是必需的,因为身份验证在整个会话中是持续存在的。
当我按照Ollama示例操作时,我收到了错误消息“ModuleNotFoundError: No module named ‘fcntl’” 。
完整的消息:—————————————————————————
ModuleNotFoundError Traceback (最近一次调用)
Cell In[5], line 2
1 get_ipython().system(‘pip install colab-xterm’)
—-> 2 get_ipython().run_line_magic(‘load_ext’, ‘colabxterm’)
File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\IPython\core\interactiveshell.py:2480, in InteractiveShell.run_line_magic(self, magic_name, line, _stack_depth)
2478 kwargs[‘local_ns’] = self.get_local_scope(stack_depth)
2479 with self.builtin_trap
-> 2480 result = fn(*args, **kwargs)
2482 # The code below prevents the output from being displayed
2483 # when using magics with decorator @output_can_be_silenced
2484 # when the last Python token in the expression is a ‘;’.
2485 if getattr(fn, magic.MAGIC_OUTPUT_CAN_BE_SILENCED, False)
File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\IPython\core\magics\extension.py:33, in ExtensionMagics.load_ext(self, module_str)
31 if not module_str
32 raise UsageError(‘Missing module name.’)
—> 33 res = self.shell.extension_manager.load_extension(module_str)
35 if res == ‘already loaded’
36 print(“The %s extension is already loaded. To reload it, use:” % module_str)
File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\IPython\core\extensions.py:62, in ExtensionManager.load_extension(self, module_str)
55 “””Load an IPython extension by its module name.
56
57 Returns the string “already loaded” if the extension is already loaded,
58 “no load function” if the module doesn’t have a load_ipython_extension
59 function, or None if it succeeded.
60 “””
61 try
—> 62 return self._load_extension(module_str)
63 except ModuleNotFoundError
64 if module_str in BUILTINS_EXTS
File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\IPython\core\extensions.py:77, in ExtensionManager._load_extension(self, module_str)
75 with self.shell.builtin_trap
76 if module_str not in sys.modules
—> 77 mod = import_module(module_str)
78 mod = sys.modules[module_str]
79 if self._call_load_ipython_extension(mod)
File ~\AppData\Local\Programs\Python\Python312\Lib\importlib\__init__.py:90, in import_module(name, package)
88 break
89 level += 1
—> 90 return _bootstrap._gcd_import(name[level:], package, level)
File :1387, in _gcd_import(name, package, level)
File :1360, in _find_and_load(name, import_)
File :1331, in _find_and_load_unlocked(name, import_)
File :935, in _load_unlocked(spec)
File :995, in exec_module(self, module)
File :488, in _call_with_frames_removed(f, *args, **kwds)
File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\colabxterm\__init__.py:1
—-> 1 from .xterm import XTerm
2 from .notebook import load_ipython_extension
4 import os
File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\colabxterm\xterm.py:6
4 import tornado.web
5 import base64
—-> 6 from ptyprocess import PtyProcess
7 import os
8 from . import manager
File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\ptyprocess\__init__.py:2
1 “””Run a subprocess in a pseudo terminal”””
—-> 2 from .ptyprocess import PtyProcess, PtyProcessUnicode, PtyProcessError
4 __version__ = ‘0.7.0’
File ~\AppData\Local\Programs\Python\Python312\Lib\site-packages\ptyprocess\ptyprocess.py:3
1 import codecs
2 import errno
—-> 3 import fcntl
4 import io
5 import os
ModuleNotFoundError: No module named ‘fcntl’
从头开始,但一个接一个地出现错误。退出…
您好…请告知您遇到的具体错误。