前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >《书生大模型实战营第3期》进阶岛 第6关: MindSearch CPU-only 版部署

《书生大模型实战营第3期》进阶岛 第6关: MindSearch CPU-only 版部署

作者头像
流川疯
发布2024-08-24 13:40:40
1900
发布2024-08-24 13:40:40
举报
文章被收录于专栏:流川疯编写程序的艺术
MindSearch 简介

MindSearch是一个开源的人工智能搜索引擎框架,其性能与Perplexy.AI Pro相当。部署你自己的困惑.ai风格的搜索引擎!

MindSearch is an open-sourced AI search engine framework, with comparable performance with Perplexity.ai Pro. Deploy your own Perplexity.ai style search engine!

官网:

  • https://mindsearch.netlify.app/

论文:

  • https://arxiv.org/pdf/2407.20183

代码:

  • https://github.com/InternLM/MindSearch

项目体验:

  • https://mindsearch.openxlab.org.cn

MindSearch框架的工作原理和工作流程

这张图描述的是MindSearch框架的工作原理和工作流程,它由两个主要部分组成:

  • WebPlanner
  • WebSearcher

WebPlanner:作为高层规划器,WebPlanner负责组织推理步骤和协调多个WebSearcher的活动。 它通过创建和扩展一个动态图(InitGraph和Add node and edge)来模拟问题的解决过程。 图中展示了如何将用户查询分解为多个子问题(Node1, Node2, … Node-N),并逐步构建图谱以解决问题。

WebSearcher:负责执行细粒度的网络搜索,根据WebPlanner的指示,搜索相关信息,并将有价值的信息摘要反馈给WebPlanner。

MindSearch 主要特点

  • 深度知识探索: MindSearch 能够浏览数百个网页,提供更广泛、更深层次的答案,帮助用户深入了解某个主题。
  • 透明的解决方案路径: MindSearch 会展示其思考路径和搜索关键词等详细信息,提高了搜索结果的可信度和可用性。
  • 多种用户界面: MindSearch 提供React、Gradio、Streamlit和本地调试等多种用户界面,方便用户根据自己的需求进行选择。
  • 动态图 [DAG] 构建: MindSearch 能够将用户查询分解为图中的子问题节点,并根据WebSearcher的搜索结果逐步扩展图,实现更灵活的搜索策略。

MindSearch CPU-only 版部署

随着硅基流动提供了免费的 InternLM2.5-7B-Chat 服务(免费的 InternLM2.5-7B-Chat 真的很香),MindSearch 的部署与使用也就迎来了纯 CPU 版本,进一步降低了部署门槛。那就让我们来一起看看如何使用硅基流动的 API 来部署 MindSearch 吧。

接下来,我们以 InternStudio 算力平台为例,来部署 CPU-only 的 MindSearch 。

1. 创建开发机 & 环境配置

由于是 CPU-only,所以我们选择 10% A100 开发机即可,镜像方面选择 cuda-12.2。

然后我们新建一个目录用于存放 MindSearch 的相关代码,并把 MindSearch 仓库 clone 下来。

代码语言:javascript
复制
mkdir -p /root/mindsearch
cd /root/mindsearch
git clone https://github.com/InternLM/MindSearch.git
cd MindSearch && git checkout b832275 && cd ..

接下来,我们创建一个 conda 环境来安装相关依赖。

代码语言:javascript
复制
# 创建环境
conda create -n mindsearch python=3.10 -y
# 激活环境
conda activate mindsearch
# 安装依赖
pip install -r /root/mindsearch/MindSearch/requirements.txt

2. 获取硅基流动 API Key

因为要使用硅基流动的 API Key,所以接下来便是注册并获取 API Key 了。

首先,我们打开 https://account.siliconflow.cn/login 来注册硅基流动的账号(如果注册过,则直接登录即可)。

在完成注册后,打开 https://cloud.siliconflow.cn/account/ak 来准备 API Key。首先创建新 API 密钥,然后点击密钥进行复制,以备后续使用。

3. 启动 MindSearch

3.1 启动后端

由于硅基流动 API 的相关配置已经集成在了 MindSearch 中,所以我们可以直接执行下面的代码来启动 MindSearch 的后端。

代码语言:javascript
复制
export SILICON_API_KEY=第二步中复制的密钥
conda activate mindsearch
cd /root/mindsearch/MindSearch
python -m mindsearch.app --lang cn --model_format internlm_silicon --search_engine DuckDuckGoSearch
3.2 启动前端

在后端启动完成后,我们打开新终端运行如下命令来启动 MindSearch 的前端。

代码语言:javascript
复制
conda activate mindsearch
cd /root/mindsearch/MindSearch
python frontend/mindsearch_gradio.py

最后,我们把 8002 端口和 7882 端口都映射到本地。可以在本地的 powershell 中执行如下代码:

代码语言:javascript
复制
ssh -CNg -L 8002:127.0.0.1:8002 -L 7882:127.0.0.1:7882 root@ssh.intern-ai.org.cn -p <你的 SSH 端口号>

然后,我们在本地浏览器中打开 localhost:7882 即可体验啦。

如果遇到了 timeout 的问题,可以按照 文档 换用 Bing 的搜索接口。

4. 部署到 HuggingFace Space

最后,我们来将 MindSearch 部署到 HuggingFace Space。

我们首先打开 https://huggingface.co/spaces ,并点击 Create new Space,如下图所示。

在输入 Space name 并选择 License 后,选择配置如下所示。

然后,我们进入 Settings,配置硅基流动的 API Key。如下图所示。

选择 New secrets,name 一栏输入 SILICON_API_KEY,value 一栏输入你的 API Key 的内容。

最后,我们先新建一个目录,准备提交到 HuggingFace Space 的全部文件。

代码语言:javascript
复制
# 创建新目录
mkdir -p /root/mindsearch/mindsearch_deploy
# 准备复制文件
cd /root/mindsearch
cp -r /root/mindsearch/MindSearch/mindsearch /root/mindsearch/mindsearch_deploy
cp /root/mindsearch/MindSearch/requirements.txt /root/mindsearch/mindsearch_deploy
# 创建 app.py 作为程序入口
touch /root/mindsearch/mindsearch_deploy/app.py

其中,app.py 的内容如下:

代码语言:javascript
复制
import json
import os

import gradio as gr
import requests
from lagent.schema import AgentStatusCode

os.system("python -m mindsearch.app --lang cn --model_format internlm_silicon &")

PLANNER_HISTORY = []
SEARCHER_HISTORY = []


def rst_mem(history_planner: list, history_searcher: list):
    '''
    Reset the chatbot memory.
    '''
    history_planner = []
    history_searcher = []
    if PLANNER_HISTORY:
        PLANNER_HISTORY.clear()
    return history_planner, history_searcher


def format_response(gr_history, agent_return):
    if agent_return['state'] in [
            AgentStatusCode.STREAM_ING, AgentStatusCode.ANSWER_ING
    ]:
        gr_history[-1][1] = agent_return['response']
    elif agent_return['state'] == AgentStatusCode.PLUGIN_START:
        thought = gr_history[-1][1].split('```')[0]
        if agent_return['response'].startswith('```'):
            gr_history[-1][1] = thought + '\n' + agent_return['response']
    elif agent_return['state'] == AgentStatusCode.PLUGIN_END:
        thought = gr_history[-1][1].split('```')[0]
        if isinstance(agent_return['response'], dict):
            gr_history[-1][
                1] = thought + '\n' + f'```json\n{json.dumps(agent_return["response"], ensure_ascii=False, indent=4)}\n```'  # noqa: E501
    elif agent_return['state'] == AgentStatusCode.PLUGIN_RETURN:
        assert agent_return['inner_steps'][-1]['role'] == 'environment'
        item = agent_return['inner_steps'][-1]
        gr_history.append([
            None,
            f"```json\n{json.dumps(item['content'], ensure_ascii=False, indent=4)}\n```"
        ])
        gr_history.append([None, ''])
    return


def predict(history_planner, history_searcher):

    def streaming(raw_response):
        for chunk in raw_response.iter_lines(chunk_size=8192,
                                             decode_unicode=False,
                                             delimiter=b'\n'):
            if chunk:
                decoded = chunk.decode('utf-8')
                if decoded == '\r':
                    continue
                if decoded[:6] == 'data: ':
                    decoded = decoded[6:]
                elif decoded.startswith(': ping - '):
                    continue
                response = json.loads(decoded)
                yield (response['response'], response['current_node'])

    global PLANNER_HISTORY
    PLANNER_HISTORY.append(dict(role='user', content=history_planner[-1][0]))
    new_search_turn = True

    url = 'http://localhost:8002/solve'
    headers = {'Content-Type': 'application/json'}
    data = {'inputs': PLANNER_HISTORY}
    raw_response = requests.post(url,
                                 headers=headers,
                                 data=json.dumps(data),
                                 timeout=20,
                                 stream=True)

    for resp in streaming(raw_response):
        agent_return, node_name = resp
        if node_name:
            if node_name in ['root', 'response']:
                continue
            agent_return = agent_return['nodes'][node_name]['detail']
            if new_search_turn:
                history_searcher.append([agent_return['content'], ''])
                new_search_turn = False
            format_response(history_searcher, agent_return)
            if agent_return['state'] == AgentStatusCode.END:
                new_search_turn = True
            yield history_planner, history_searcher
        else:
            new_search_turn = True
            format_response(history_planner, agent_return)
            if agent_return['state'] == AgentStatusCode.END:
                PLANNER_HISTORY = agent_return['inner_steps']
            yield history_planner, history_searcher
    return history_planner, history_searcher


with gr.Blocks() as demo:
    gr.HTML("""<h1 align="center">MindSearch Gradio Demo</h1>""")
    gr.HTML("""<p style="text-align: center; font-family: Arial, sans-serif;">MindSearch is an open-source AI Search Engine Framework with Perplexity.ai Pro performance. You can deploy your own Perplexity.ai-style search engine using either closed-source LLMs (GPT, Claude) or open-source LLMs (InternLM2.5-7b-chat).</p>""")
    gr.HTML("""
    <div style="text-align: center; font-size: 16px;">
        <a href="https://github.com/InternLM/MindSearch" style="margin-right: 15px; text-decoration: none; color: #4A90E2;">🔗 GitHub</a>
        <a href="https://arxiv.org/abs/2407.20183" style="margin-right: 15px; text-decoration: none; color: #4A90E2;">📄 Arxiv</a>
        <a href="https://huggingface.co/papers/2407.20183" style="margin-right: 15px; text-decoration: none; color: #4A90E2;">📚 Hugging Face Papers</a>
        <a href="https://huggingface.co/spaces/internlm/MindSearch" style="text-decoration: none; color: #4A90E2;">🤗 Hugging Face Demo</a>
    </div>
    """)
    with gr.Row():
        with gr.Column(scale=10):
            with gr.Row():
                with gr.Column():
                    planner = gr.Chatbot(label='planner',
                                         height=700,
                                         show_label=True,
                                         show_copy_button=True,
                                         bubble_full_width=False,
                                         render_markdown=True)
                with gr.Column():
                    searcher = gr.Chatbot(label='searcher',
                                          height=700,
                                          show_label=True,
                                          show_copy_button=True,
                                          bubble_full_width=False,
                                          render_markdown=True)
            with gr.Row():
                user_input = gr.Textbox(show_label=False,
                                        placeholder='帮我搜索一下 InternLM 开源体系',
                                        lines=5,
                                        container=False)
            with gr.Row():
                with gr.Column(scale=2):
                    submitBtn = gr.Button('Submit')
                with gr.Column(scale=1, min_width=20):
                    emptyBtn = gr.Button('Clear History')

    def user(query, history):
        return '', history + [[query, '']]

    submitBtn.click(user, [user_input, planner], [user_input, planner],
                    queue=False).then(predict, [planner, searcher],
                                      [planner, searcher])
    emptyBtn.click(rst_mem, [planner, searcher], [planner, searcher],
                   queue=False)

demo.queue()
demo.launch(server_name='0.0.0.0',
            server_port=7860,
            inbrowser=True,
            share=True)

在最后,将 /root/mindsearch/mindsearch_deploy 目录下的文件(使用 git)提交到 HuggingFace Space 即可完成部署了。


任务

  • https://github.com/InternLM/Tutorial/blob/camp3/docs/L2/MindSearch/task.md

记录复现过程并截图

基础任务(完成此任务即完成闯关) 按照教程,将 MindSearch 部署到 HuggingFace,并提供截图。

后端主要是这几个接口

如何根据三岁小孩的性格特点,给他制定对应的教育规划?

为了回答这个问题,我们需要首先了解三岁小孩的性格特点,然后根据这些特点制定相应的教育规划。我们将这个问题拆分为两个子问题:

  • 了解三岁小孩的性格特点。
  • 根据性格特点制定教育规划。

接下来,我将使用 WebSearchGraph 类来构建搜索图并逐步解答这个问题。

代码语言:javascript
复制
from ilagent.agents.python_web import WebSearchGraph
graph = WebSearchGraph()
graph.add_root_node(node_content="如何根据三岁小孩的性格特点,给他制定对应的教育规划?", node_name="root")

# 添加第一个子问题节点:了解三岁小孩的性格特点
graph.add_node(
    node_name="性格特点",
    node_content="三岁小孩的性格特点有哪些?")
graph.add_edge(start_node="root", end_node="性格特点")

# 添加第二个子问题节点:根据性格特点制定教育规划
graph.add_node(
    node_name="教育规划",
    node_content="如何为具有特定性格特质的三歲孩童制定合适的教育计划?")
graph.add_edge(start_node="root", end_node="教育规划")

# 获取节点信息以确认设置是否正确
graph.node("性格特点"), graph.node("教育规划")
代码语言:javascript
复制
{
    "name": "BingBrowser.search",
    "parameters": {
        "query": [
            "三岁小孩的性格特点",
            "三岁儿童的心理发展特征",
            "三岁孩子的行为特征和情感表达",
            "如何理解三岁小孩的行为和性格"
        ]
    }
}

三岁小孩的性格特点和教育规划是一个复杂但重要的主题。了解三岁小孩的性格特点可以帮助家长和教育者更好地理解他们的需求,从而制定出更加有效的教育计划。以下将详细探讨三岁小孩的性格特点以及基于这些特点的教育规划。 三岁小孩的性格特点

  1. 好奇心强 三岁的孩子对周围的世界充满好奇,他们喜欢探索新事物,提出各种问题[[BingBrowser.search[0]]]。这种好奇心是学习的动力源泉,家长应鼓励他们进行探索和发现。
  2. 情绪波动大 三岁的孩子情绪波动较大,容易受到外界环境的影响而产生情绪变化[[BingBrowser.search[1]]]。家长需要学会识别孩子的情绪变化并给予适当的回应和引导。
  3. 自我中心 这个年龄段的孩子往往以自我为中心,难以从他人的角度考虑问题[[BingBrowser.search[2]]]。家长可以通过角色扮演等活动帮助孩子发展共情能力和社会技能。 基于性格特点的教育规划
  4. 创造丰富的学习环境 由于三岁孩子的好奇心强,为他们创造一个充满探索和学习机会的环境至关重要[[BingBrowser.search[0]]]。这包括提供各种玩具、书籍、艺术材料等资源,让他们自由地进行探索和学习活动。
  5. 情感教育和支持 鉴于三岁的孩子在情感上容易波动且依赖性强[[BingBrowser.search[1]]],父母应该提供稳定的情感支持和安全感。通过日常互动如拥抱、讲故事等方式来增强孩子的安全感和自信心[[3]][[4]]. a. 建立稳定的日常生活 规律的作息时间和固定的日常活动可以帮助孩子建立安全感并减少焦虑感[[5]][[6]]. b. 积极倾听与回应 当孩子在表达自己的感受时(无论是快乐还是悲伤),父母应该积极倾听并提供适当的回应或安慰词句如“我明白”或“这很正常”等来帮助他们处理情绪[[7]][[8]]. c. 培养积极的社交技能 通过游戏和其他社交活动促进孩子的社交技能发展是必要的步骤之一 [[9]][[10]].例如,可以安排与其他同龄儿童的玩耍时间,或者参与集体游戏以提高合作能力和沟通技巧. 结论 综上所述,了解三岁小孩的性格特点是制定有效教育计划的基础步骤之一 [[11]].根据他们的好奇心、情感波动大和自我中心的特点,我们可以采取相应的措施来满足他们的需求和发展潜力:创建丰富的学习环境以激发好奇心;提供稳定的情感支持和积极的社交互动;以及建立规律的日常生活节奏以增强安全感与自信心. 这些策略不仅有助于满足当前的需求,也为未来的学习和成长奠定了坚实的基础 [[12]][[13]].因此,深入理解并应用这些策略对于培养健康发展的三岁以上儿童至关重要.

hugging face 部署 直接 git clone 没反应,只好手工扔上去额

  • https://huggingface.co/spaces/shiter/TEST_MINDSEARCH

cpu 版本也是非常的快,点赞

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-08-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • MindSearch 简介
  • MindSearch框架的工作原理和工作流程
  • MindSearch 主要特点
  • MindSearch CPU-only 版部署
    • 1. 创建开发机 & 环境配置
      • 2. 获取硅基流动 API Key
        • 3. 启动 MindSearch
          • 3.1 启动后端
          • 3.2 启动前端
        • 4. 部署到 HuggingFace Space
        • 任务
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档