从未想象构建本地大语言模型应用会如此简单

openlab_96bf3613 更新于 2月前

概述
目前OpenVINO™ 2024.3 最新版本现已开放下载!OpenVINO™一直致力于各项性能的研发,不断优化用户体验,拓宽 OpenVINO™ 的功能边界,让AI能够更加简单!
在当今时代,生成式 AI 正被应用程序设计人员以惊人的速度广泛应用。这种应用不仅体现在传统的 REST API 形式上,即通过商业云服务模型来实现,而且在客户端和边缘领域也日益凸显。如今,越来越多的数据在客户端得到处理,借助 AIPC(具体名称可根据实际情况补充),我们开始看到更多的机遇。其中一种令人瞩目的场景便是人工智能助手,它能够生成各种文本内容,如邮件草稿、文档摘要以及针对文档内容的答案等等。而这一切背后的强大支撑来自于 LLM(大型语言模型)以及不断发展壮大的 SLM(小型语言模型)系列。
从 OpenVINO™ 2024.2 版本开始,全新推出的 OpenVINO™ GenAI 软件包以及专门针对 LLM 的 API,犹如一把神奇的钥匙,为开发者、甚至普通用户开启了在本地构建 LLM 应用的便捷之门。它的出现,使得在本地构建 LLM 应用变得前所未有的简单。无论是经验丰富、专业精湛的开发人员,还是对人工智能充满无限热情与好奇的爱好者,都能轻松上手,踏上属于自己的人工智能应用构建之旅。在这里,他们可以充分发挥自己的创造力和想象力,将先进的技术与独特的需求相结合,打造出一个个独具特色的人工智能应用,为我们的生活和工作带来更多的便利与惊喜。
旧版本构建方式
在旧版本中,我们需要安装一系列的依赖项,其中包括 nncf、torch、datasets、accelerate、gradio、onnx 等等。然而,在安装过程中,常常会由于依赖版本不兼容等问题,导致模型运行出现异常情况。这不仅给开发者带来了诸多困扰,也在一定程度上影响了项目的进展和效率。复杂的依赖关系和潜在的版本冲突,使得旧版本的使用体验不尽如人意,增加了开发过程中的不确定性和风险。

以下是安装的依赖代码:

%pip install -Uq pip
 
%pip uninstall -q -y optimum optimum-intel
 
%pip install --pre -Uq "openvino>=2024.2.0" openvino-tokenizers[transformers] --extra-index-url https://storage.openvinotoolkit.org/simple/wheels/nightly
 
%pip install -q --extra-index-url https://download.pytorch.org/whl/cpu\
 
"git+https://github.com/huggingface/optimum-intel.git"\
 
"git+https://github.com/openvinotoolkit/nncf.git"\
 
"torch>=2.1"\
 
"datasets" \
 
"accelerate" \
 
"gradio>=4.19" \
 
"onnx<=1.16.1; sys_platform=='win32'" "einops" "transformers>=4.43.1" "transformers_stream_generator" "tiktoken" "bitsandbytes"

在安装完成之后,我们紧接着需要着手构建所需的应用程序。然而,这个过程中需要处理诸如 tokens、processor 等内容。不得不说,这对于初学者而言,着实不太友好。初学者在面对这些复杂的处理要求时,往往会感到困惑和无从下手,因为他们可能对这些概念还不够熟悉,缺乏相应的经验和技能来有效地处理它们。同时,对于后期的维护工作来说,也存在一定的难度。后期维护人员需要深入理解这些 tokens 和 processor 的作用和相互关系,以便在出现问题时能够准确地进行故障排查和修复。这不仅需要较高的技术水平,还需要耗费大量的时间和精力。以下是相关的代码参考:

def bot(history, temperature, top_p, top_k, repetition_penalty, conversation_id):

# Construct the input message string for the model by concatenating the current system message and conversation history

# Tokenize the messages string

input_ids = convert_history_to_token(history)

if input_ids.shape[1] > 2000:

history = [history[-1]]

input_ids = convert_history_to_token(history)

streamer = TextIteratorStreamer(tok, timeout=30.0, skip_prompt=True, skip_special_tokens=True)

generate_kwargs = dict(

input_ids=input_ids,

max_new_token***ax_new_tokens,

temperature=temperature,

do_sample=temperature > 0.0,

top_p=top_p,

top_k=top_k,

repetition_penalty=repetition_penalty,

streamer=streamer,

)

if stop_tokens is not None:

generate_kwargs["stopping_criteria"] = StoppingCriteriaList(stop_tokens)



stream_complete = Event()



def generate_and_signal_complete():

"""
genration function for single thread
"""

global start_time

ov_model.generate(**generate_kwargs)

stream_complete.set()



t1 = Thread(target=generate_and_signal_complete)

t1.start()



# Initialize an empty string to store the generated text

partial_text = ""

for new_text in streamer:

partial_text = text_processor(partial_text, new_text)

history[-1][1] = partial_text

yield history

具体代码可以查看:https://github.com/openvinotoolkit/openvino_notebook***lob/latest/notebooks/llm-chatbot/llm-chatbot.ipynb
GenAI
在OpenVINO™ 24.2推出 OpenVINO™ GenAI 软件包以及 LLM 特定 API!如今,生成式 AI 正被应用程序设计人员迅速采用,其应用场景不仅局限于传统的 REST API 形式,即通过商业云服务模型来实现,而且在客户端和边缘设备上也日益普及。越来越多的数据在客户端得到处理,借助 AIPC,我们开始看到更多的机遇。其中一种典型场景便是人工智能助手,它能够生成各种文本内容,如邮件草稿、文档摘要以及对文档内容的答案等等。而这一切都得益于 LLM(大型语言模型)以及不断发展壮大的 SLM(小型语言模型)系列的有力支持。
OpenVINO™ GenAI这个软件包充分利用了 OpenVINO™以及其中的 OpenVINO™ Tokenizers。如果您计划运行 LLM,那么安装此软件包便已足够。经典的 OpenVINO™ API 同样支持其他类型的模型,因此现在构建流水线变得更加容易。我们的安装选项也进行了更新,以便能够准确反映并指导新软件包的使用。所以,请在那里查看最适合您的选项。经典的 OpenVINO™软件包依然存在,如果您目前暂不打算使用生成式 API,那么可以继续使用 OpenVINO™软件包。
为了通过 LLM 生成结果,应用程序需要执行一整套操作流水线。首先,对输入文本进行分词处理;接着,处理输入的上下文;然后,迭代生成模型答案的后续输出分词;最后,将答案从分词解码为纯文本。每一个分词的生成都涉及到一次推理调用,随后还需要进行后续逻辑处理以选择合适的分词。这种逻辑可以是贪婪搜索的形式,即选择最有可能的分词;也可以是波束搜索的形式,也就是保持少量的序列并从中选择最好的。虽然 OpenVINO™在推理方面表现卓越,但正如我们刚才所讨论的,仅仅依靠推理还不足以涵盖整个文本生成的流水线。在 2024.2 版本之前,我们提供了一些帮助程序(分词器和示例)来实现这一目标,但应用程序必须使用这些组件来实现整个生成逻辑。而现在,这种情况正在发生改变。
在 24.2 版本中,同时引入了特定于 LLM 的 API。这些 API 巧妙地隐藏了内部生成循环的复杂性,并且显著减少了应用程序中需要编写的代码量。通过使用特定于 LLM 的 API,您可以轻松加载模型,向其传递上下文,并在短短几行代码中就能够获得响应。在内部,OpenVINO™将对输入文本进行分词化处理,在您选择的设备上执行生成循环,并为您提供最终的答案。
使用GenAI
若要完全使用 GenAI API,仅仅需要安装两个极为重要的库。其一为 OpenVINO™ GenAI,这个库在处理大语言模型方面发挥着关键作用。它凭借先进的算法和高效的架构,能够对大语言模型进行精准而快速的处理,为用户提供高质量的语言处理服务。其二是 optimum-intel,它主要充当着将 Hugging Face 上丰富多样的 LLM 模型下载并转换为 OpenVINO™ 模型的重要工具。Hugging Face 作为一个拥有众多强大语言模型的平台,通过 optimum-intel 的作用,可以将这些优秀的模型资源转化为 OpenVINO™ 模型,从而更好地适应不同的应用场景和需求。这两个库相互配合,为开发者和使用者在人工智能领域的探索和创新提供了有力的支持。
安装依赖

# 安装OpenVINO™ GenAI

pip install openvino-genai==2024.3.0

# 安装optimum-intel

pip install optimum optimum-intel

(注意:最好创建一个虚拟环境)

python -m venv openvino_env

验证是否安装成功:
OpenVINO™ GenAI: 需要再python代码中
下载模型
在人工智能的应用中,我们拥有多种可供选择的强大模型。其中,intel 针对聊天场景进行微调的模型 Tiny Llama(英文),能够在英文聊天场景中为用户提供高质量的交互体验。此外,还有中文模型 chatglm3 - 6b(未验证)可供尝试。不过,在使用这些模型时,我们应确保其可靠性和适用性。具体官方验证过的模型可以查看网址:https://github.com/openvinotoolkit/openvino_notebook***lob/latest/utils/llm_config.py。需要注意的是,这里列出的是旧代码验证过的模型,随着技术的不断发展和更新,可能会有新的模型出现并经过验证。因此,在选择和使用模型时,我们应密切关注官方渠道的信息更新,以确保能够获得最佳的性能和体验。同时,对于未经验证的模型,我们应谨慎使用,充分评估其风险和潜在问题,以保障人工智能应用的稳定和可靠。

optimum-cli export openvino --model {模型} --weight-format {模型格式} --trust-remote-code {保存位置}

{模型} : 为模型的组织/模型,如TinyLlama/TinyLlama-1.1B-Chat-v1.0
{模型格式}:模型格式我们可以下载int4,int8,fp16的格式
{保存位置}:模型所保存的位置

mkdir TinyLlama

cd TinyLlama

optimum-cli export openvino --model "TinyLlama/TinyLlama-1.1B-Chat-v1.0" --weight-format int4 --trust-remote-code ./

如果不出现问题的话,将在TinyLlama目录下会生成openvino.xml 和 openvino.bin文件,以及一些其他需要的配置文件,当有这两个文件,一般代表下载成功了。
使用OpenVINO™ GenAI API
现在我们已经完成依赖安装、模型下载,那么我们可以使用三行代码即可实现大语言模型的推理。

import openvino_genai as ov_genai

pipe = ov_genai.LLMPipeline(model_path, "CPU")

print(pipe.generate("The Sun is yellow because", max_new_tokens=100))

(注意:model_path 不需要写具体的xml文件,旧版本之前使用模型文件都是指明模型的xml文件,这里只需要将模型所在的路径写进去即可。)

总结
通过上述内容,我们大致可以看出,在 24.2 版本之后的 GenAI API 下,构建一个本地 LLM 应用变得极为简单。若无特殊需求,仅需三行代码即可搞定一切,无需再像以往那样编写大量代码。当然,如果本地 LLM 性能欠佳,Intel 可通过添加其 ARC 系列独立显卡进行加速,以实现进一步的性能提升。为助力实现 LLM 部署特性,Intel 始终专注于加速 GPU 的 LLM 推理性能,涵盖集成显卡与独立显卡。将负载卸载至 GPU,一方面是因其特性适合处理此类工作负载,另一方面则是为了保持 CPU 可用。因此,推理期间的 CPU 负载在此类情况下至关重要。Intel 一直在竭力优化 CPU 端负载,将主机代码延迟至少减少一半。这也使得 Intel 能够实现更出色的 GPU 特性,因为内核调度如今更加高效。

0个评论