0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

利用OpenVINO搭建本地智能體流水線

英特爾物聯(lián)網(wǎng) ? 來源:英特爾物聯(lián)網(wǎng) ? 2024-10-25 16:01 ? 次閱讀

作者

楊亦誠 英特爾 AI 軟件工程師

智能體 AI Agent 作為大模型的衍生應(yīng)用,具有對任務(wù)的理解、規(guī)劃與行動能力。它可以通過將一個復(fù)雜的用戶請求拆分成不同的子任務(wù),并依次調(diào)用外部工具來解決這些任務(wù),并將其中每個任務(wù)步驟的執(zhí)行結(jié)果,按預(yù)先規(guī)劃的邏輯串聯(lián)起來,從而達成最終的目的。

接下來我們就通過一個例子,演示如何利用 OpenVINO 工具套件在你的電腦上的一步步搭建本地智能體流水線。

1轉(zhuǎn)換壓縮LLM

首先要需要利用 Hugging Face 的 Optimum-intel 命令行工具將原始模型轉(zhuǎn)化為 OpenVINO 的 IR 格式,并對其進行 int4 量化壓縮,以實現(xiàn)本地部署的目的。這里我們選擇通義千問團隊近期發(fā)布的 Qwen2.5 大語言模型為例,它可以支持多種不同語言。其中最小3B參數(shù)版本的模型便可以對本示例進行復(fù)現(xiàn)。

 !optimum-cli export openvino --model "Qwen/Qwen2.5-3B-Instruct"--task text-generation-with-past --trust-remote-code --weight-format int4 --group-size 128 --ratio 1.0 --sym “Qwen2.5-3B-Instruct-int4-ov”

其中"Qwen/Qwen2.5-3B-Instruct"為模型的 HuggingFace 的模型 ID,如果在訪問 Hugging Face 模型倉庫時,發(fā)現(xiàn)網(wǎng)絡(luò)限制,也可以通過 ModelScope 將原始模型下載到本地,并將該模型 ID 替換為模型的本地路徑,例如:"./model/Qwen2.5-3B-Instruct"。

2創(chuàng)建LLM任務(wù)

第二步同樣可以利用 Optimum-intel 提供的 OpenVINO API 接口將模型部署在指定的硬件平臺,這里可以通過指定 device=”gpu” 將模型加載到任意一個 Intel 的獨顯或是集顯上,以最大化模型推理性能。

tokenizer = AutoTokenizer.from_pretrained(llm_model_path, trust_remote_code=True)


ov_config = {hints.performance_mode(): hints.PerformanceMode.LATENCY, streams.num(): "1", props.cache_dir(): ""}


llm = OVModelForCausalLM.from_pretrained(
    llm_model_path,
    device=llm_device.value,
    ov_config=ov_config,
    config=AutoConfig.from_pretrained(llm_model_path, trust_remote_code=True),
    trust_remote_code=True,
)

除了對模型對象進行初始化以外,還需要創(chuàng)建針對模型推理輸出的后處理函數(shù),主要目的是為了實現(xiàn)流式輸出,以及設(shè)置停止字符,讓 LLM 在調(diào)用工具前停止推理任務(wù)。

def text_completion(prompt: str, stop_words) -> str:
  im_end = "<|im_end|>"
  if im_end not in stop_words:
    stop_words = stop_words + [im_end]
  streamer = TextStreamer(tokenizer, timeout=60.0, skip_prompt=True, skip_special_tokens=True)


  stopping_criteria = StoppingCriteriaList([StopSequenceCriteria(stop_words, tokenizer)])
  input_ids = torch.tensor([tokenizer.encode(prompt)])
  generate_kwargs = dict(
    input_ids=input_ids,
    streamer=streamer,
    stopping_criteria=stopping_criteria,
  )
  output = llm.generate(**generate_kwargs)
  output = output.tolist()[0]
  output = tokenizer.decode(output, errors="ignore")
  assert output.startswith(prompt)
  output = output[len(prompt) :].replace("<|endoftext|>", "").replace(im_end, "")


  for stop_str in stop_words:
    idx = output.find(stop_str)
    if idx != -1:
      output = output[: idx + len(stop_str)]
  return output

3定義智能體Prompt模板

這一步也是決定智能體工作模式的關(guān)鍵,通過 Prompt 模板,我們將教會 LLM 一個常規(guī)任務(wù)的解決路徑,以及有哪些類別的外部工具可能幫助它解決特定問題??梢钥吹皆谙旅孢@個典型 ReAct 類 Prompt 模板中,我們定義外部工具的具體信息模板,以及 LLM 在執(zhí)行任務(wù)過程中的輸出模板,其中 “Observation” 后內(nèi)容為外部工具調(diào)用后返回的結(jié)果,并非由 LLM 直接生成??梢钥吹皆谠撃0逯?, LLM 可能會被執(zhí)行多次,直到上下文中的信息足夠回答用戶請求。

TOOL_DESC = """{name_for_model}: Call this tool to interact with the {name_for_human} API. What is the {name_for_human} API useful for? {description_for_model} Parameters: {parameters}"""


PROMPT_REACT = """Answer the following questions as best you can. You have access to the following APIs:


{tools_text}


Use the following format:


Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [{tools_name_text}]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can be repeated zero or more times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question


Begin!


Question:{query}"""

4輸出過濾與工具定義

由于智能體需要和外部工具頻繁交互,發(fā)出指令并獲取工具反饋結(jié)果,因此我們需要在 LLM 輸出時,判斷哪些關(guān)鍵詞代表模型需要調(diào)用工具,哪些關(guān)鍵詞代表收集工具反饋結(jié)果。在這里例子中,當 LLM 輸出 “Action:" 后的字符,代表接下來需要調(diào)用的工具函數(shù)名稱,輸出 “Action Input” 后的字符,代表輸入給該工具的輸入?yún)?shù),以及 “Observation” 代表接下來需要直接輸出工具的執(zhí)行結(jié)果,因此它也是終止當前 LLM 推理任務(wù)的特殊字符。

def parse_latest_tool_call(text):
    tool_name, tool_args = "", ""
    i = text.rfind("
Action:")
    j = text.rfind("
Action Input:")
    k = text.rfind("
Observation:")
    if 0 <= i < j:  # If the text has `Action` and `Action input`,
        if k < j:  # but does not contain `Observation`,
            # then it is likely that `Observation` is ommited by the LLM,
            # because the output text may have discarded the stop word.
            text = text.rstrip() + "
Observation:"  # Add it back.
        k = text.rfind("
Observation:")
        tool_name = text[i + len("
Action:") : j].strip()
        tool_args = text[j + len("
Action Input:") : k].strip()
        text = text[:k]
????return?tool_name,?tool_args,?text

為了告訴 LLM 什么時候該調(diào)用什么工具,以及這些工具的基本輸入和輸入?yún)?shù)格式,我們在完成工具函數(shù)的編寫后,還需要以字典的形式,將這些信息送入先前定義的 Prompt 模板中,參考示例如下:

tools = [
    {
        "name_for_human": "get weather",
        "name_for_model": "get_weather",
        "description_for_model": 'Get the current weather in a given city name."',
        "parameters": [
            {
                "name": "city_name",
                "description": "City name",
                "required": True,
                "schema": {"type": "string"},
            }
        ],
    },
    {
        "name_for_human": "image generation",
        "name_for_model": "image_gen",
        "description_for_model": "AI painting (image generation) service, input text description, and return the image URL drawn based on text information.",
        "parameters": [
            {
                "name": "prompt",
                "description": "describe the image",
                "required": True,
                "schema": {"type": "string"},
            }
        ],
    },
]

在這個例子中,我們定義一個天氣查詢工具以及一個文生圖工具,他們分別會調(diào)用響應(yīng)的 API 服務(wù)完成響應(yīng)任務(wù)。

5構(gòu)建智能體

接下來我們需要將以上定義的函數(shù)串聯(lián)起來,構(gòu)建一個簡單的智能體流水線。第一步會將用戶請求經(jīng) Prompt 模板格式化后送入 LLM,接下來解析 LLM 輸出,并判斷是否需要調(diào)用外部工具 “Action” 。如果需要調(diào)用外部工具,則智能體會運行該工具函數(shù),獲得運行結(jié)果,最后將結(jié)果數(shù)據(jù)合并到下一輪的輸入 Prompt 中,由 LLM 判斷是否還需要再次調(diào)用其他工具,再進行一次循環(huán),如果不需要調(diào)用工具,并且當前得到的信息已經(jīng)可以滿足用戶請求,那 LLM 將整合并基于這個過程中所有的 “Observation” 信息,輸出最終答案 “Final Answer”。

    while True:
        output = text_completion(planning_prompt + text, stop_words=["Observation:", "Observation:
"])
        action, action_input, output = parse_latest_tool_call(output)
        if action:
            observation = call_tool(action, action_input)
            output += f"
Observation: = {observation}
Thought:"
            observation = f"{observation}
Thought:"
            print(observation)
            text += output
        else:
            text += output
break

該示例的運行效果如下,這里我們讓智能體“根據(jù)當前倫敦的天氣,生成一張大本鐘的照片”??梢钥吹街悄荏w按照我們既定的 Prompt 策略,將用戶問題拆分后,分別調(diào)用預(yù)先定義的不同工具,根據(jù)用戶要求得到最終結(jié)果。當然你也可以用中文向它發(fā)出請求。

query = "get the weather in London, and create a picture of Big Ben based on the weather information"


response,history=llm_with_tool(prompt=query,history=history,list_of_tool_info=tools)

“Thought: First, I need to use the get_weather API to get the current weather in London.

Action: get_weather

Action Input: {"city_name": "London"}

Observation:

{'current_condition': {'temp_C': '11', 'FeelsLikeC': '10', 'humidity': '94', 'weatherDesc': [{'value': 'Overcast'}], 'observation_time': '12:23 AM'}}

Thought:

Now that I have the weather information, I will use the image_gen API to generate an image of Big Ben based on the weather conditions.

Action: image_gen

Action Input: {"prompt": "Big Ben under overcast sky with temperature 11°C and humidity 94%"}

Observation:

{"image_url": "https://image.pollinations.ai/prompt/Big%20Ben%20under%20overcast%20sky%20with%20temperature%2011%C2%B0C%20and%20humidity%2094%25"}

Thought:

The image has been generated successfully.

Final Answer: The current weather in London is overcast with a temperature of 11°C and humidity of 94%. Based on this information, here is the image of Big Ben under an overcast sky: ![](https://image.pollinations.ai/prompt/Big%20Ben%20under%20overcast%20sky%20with%20temperature%2011%C2%B0C%20and%20humidity%2094%25)“

6總結(jié)

該示例以 OpenVINO 作為 LLM 的推理后端,一步步構(gòu)建起了一個簡單的智能體流水線,可以看到這個示例中除了 Optimum-intel,沒有其他外部依賴需要安裝,因此它也是一個非常基礎(chǔ)的的智能體構(gòu)建過程。除此以外,該示例使用 3B 大小 SLM 便可以實現(xiàn)該智能體的構(gòu)建,同時帶來不錯的性能表現(xiàn),是非常適合在本地構(gòu)建的智能體示例。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 流水線
    +關(guān)注

    關(guān)注

    0

    文章

    115

    瀏覽量

    25546
  • AI
    AI
    +關(guān)注

    關(guān)注

    87

    文章

    29434

    瀏覽量

    267730
  • 模型
    +關(guān)注

    關(guān)注

    1

    文章

    3073

    瀏覽量

    48581
  • OpenVINO
    +關(guān)注

    關(guān)注

    0

    文章

    82

    瀏覽量

    156

原文標題:從0到1構(gòu)建 OpenVINO? 智能體流水線|開發(fā)者實戰(zhàn)

文章出處:【微信號:英特爾物聯(lián)網(wǎng),微信公眾號:英特爾物聯(lián)網(wǎng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    FPGA中的流水線設(shè)計

    令預(yù)取、 譯碼、 執(zhí)行、 寫回結(jié)果, openrisc采用的是 5 級整數(shù)流水線。當然它們的核心思想都是利用并行執(zhí)行提高效率??偨Y(jié)一下,流水線就是插入寄存器,以面積換取速度。`
    發(fā)表于 10-26 14:38

    周期精確的流水線仿真模型

    使用軟件仿真硬件流水線是很耗時又復(fù)雜的工作,仿真過程中由于流水線的沖突而導致運行速度緩慢。本文通過對嵌入式處理器的流水線, 指令集, 設(shè)備控制器等內(nèi)部結(jié)構(gòu)的分析和
    發(fā)表于 12-31 11:30 ?9次下載

    什么是流水線技術(shù)

    什么是流水線技術(shù) 流水線技術(shù)
    發(fā)表于 02-04 10:21 ?3907次閱讀

    流水線中的相關(guān)培訓教程[1]

    流水線中的相關(guān)培訓教程[1]  學習目標     理解流水線中相關(guān)的分類及定義;
    發(fā)表于 04-13 15:56 ?1020次閱讀

    流水線中的相關(guān)培訓教程[4]

    流水線中的相關(guān)培訓教程[4] 下面討論如何利用編譯器技術(shù)來減少這種必須的暫停,然后論述如何在流水線中實現(xiàn)數(shù)據(jù)相關(guān)檢測和定向。
    發(fā)表于 04-13 16:09 ?4689次閱讀

    電鍍流水線的PLC控制

    電鍍流水線的PLC控制電鍍流水線的PLC控制電鍍流水線的PLC控制
    發(fā)表于 02-17 17:13 ?36次下載

    裝配流水線控制系統(tǒng)設(shè)計

    裝配流水線控制系統(tǒng)設(shè)計
    發(fā)表于 12-17 15:26 ?14次下載

    FPGA之流水線練習(3):設(shè)計思路

    流水線的平面設(shè)計應(yīng)當保證零件的運輸路線最短,生產(chǎn)工人操作方便,輔助服務(wù)部門工作便利,最有效地利用生產(chǎn)面積,并考慮流水線安裝之間的相互銜接。為滿足這些要求,在流水線平面布置時應(yīng)考慮
    的頭像 發(fā)表于 11-28 07:07 ?2288次閱讀

    FPGA之為什么要進行流水線的設(shè)計

    流水線又稱為裝配線,一種工業(yè)上的生產(chǎn)方式,指每一個生產(chǎn)單位只專注處理某一個片段的工作。以提高工作效率及產(chǎn)量;按照流水線的輸送方式大體可以分為:皮帶流水裝配線、板鏈線、倍速鏈、插件線、網(wǎng)帶線、懸掛線及滾筒
    的頭像 發(fā)表于 11-28 07:04 ?3539次閱讀

    各種流水線特點及常見流水線設(shè)計方式

    按照流水線的輸送方式大體可以分為:皮帶流水裝配線、板鏈線、倍速鏈、插件線、網(wǎng)帶線、懸掛線及滾筒流水線這七類流水線。
    的頭像 發(fā)表于 07-05 11:12 ?7151次閱讀
    各種<b class='flag-5'>流水線</b>特點及常見<b class='flag-5'>流水線</b>設(shè)計方式

    如何選擇合適的LED生產(chǎn)流水線輸送方式

    LED生產(chǎn)流水線輸送形式分為平面直線傳輸流水線、各種角度平面轉(zhuǎn)彎傳輸流水線、斜面上傳流水線、斜面下傳流水線這四種輸送方式,企業(yè)也是可以根據(jù)L
    發(fā)表于 08-06 11:53 ?981次閱讀

    嵌入式_流水線

    流水線一、定義流水線是指在程序執(zhí)行時多條指令重疊進行操作的一種準并行處理實現(xiàn)技術(shù)。各種部件同時處理是針對不同指令而言的,他們可同時為多條指令的不同部分進行工作。? 把一個重復(fù)的過程分解為若干個子過程
    發(fā)表于 10-20 20:51 ?6次下載
    嵌入式_<b class='flag-5'>流水線</b>

    FPGA中流水線的原因和方式

    本文解釋了流水線及其對 FPGA 的影響,即延遲、吞吐量、工作頻率的變化和資源利用率。
    的頭像 發(fā)表于 05-07 16:51 ?5878次閱讀
    FPGA中<b class='flag-5'>流水線</b>的原因和方式

    CPU流水線的問題

    1989 年推出的 i486 處理器引入了五級流水線。這時,在 CPU 中不再僅運行一條指令,每一級流水線在同一時刻都運行著不同的指令。這個設(shè)計使得 i486 比同頻率的 386 處理器性能提升了不止一倍。
    的頭像 發(fā)表于 09-22 10:04 ?1893次閱讀

    什么是流水線 Jenkins的流水線詳解

    jenkins 有 2 種流水線分為聲明式流水線與腳本化流水線,腳本化流水線是 jenkins 舊版本使用的流水線腳本,新版本 Jenkin
    發(fā)表于 05-17 16:57 ?1014次閱讀