书生大模型实战营(第三期闯关大挑战)- 进阶岛 第六关 MindSearch CPU-only 版部署

news2024/9/21 10:55:35

0 项目介绍

书生大模型实战营三期进阶岛 增加了MindSearch 快速部署任务关卡。之前的任务是在彩蛋岛的任务,可能之前彩蛋岛的任务中用到了DuckDuckGoSearch 这个是国外网络才好访问,实际使用过程中需要通过一些魔法才能解决此任务。很多小伙伴卡在网络这块,所以训练营对次任务进行了改进,改成了使用 HuggingFace

space +硅基流动的 API Key的方式部署。本次任务带大家一起完成HuggingFace space 这种部署方式。

如果小伙伴对之前的部署方式感兴趣可以关注这篇文章

B站

微信公众号

CSDN

系统huggingface space 体验地址

1 获取硅基流动 API Key

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

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

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

[image

2 使用github

Codespaces

image-20240823221311221

进入Codespaces 浏览器会自动在新的页面打开一个web版的vscode

image-20240823221401282

然后我们新建一个目录用于存放 MindSearch 的相关代码,并把 MindSearch 仓库 clone 下来。在终端中运行下面的命令:

mkdir -p /workspaces/mindsearch
cd /workspaces/mindsearch
git clone https://github.com/InternLM/MindSearch.git
cd MindSearch && git checkout b832275 && cd ..

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

# 创建环境
conda create -n mindsearch python=3.10 -y
# 激活环境
conda activate mindsearch
source activate
# 安装依赖
pip install -r /workspaces/mindsearch/MindSearch/requirements.txt

3.启动 MindSearch

启动后端

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

# 硅基流动 API Key
export SILICON_API_KEY=
conda activate mindsearch
cd /workspaces/mindsearch/MindSearch
python -m mindsearch.app --lang cn --model_format internlm_silicon --search_engine DuckDuckGoSearch

image-20240823223401930

看到以上画面服务已经启动完成。

启动前端

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

conda activate mindsearch
cd /workspaces/mindsearch/MindSearch
python frontend/mindsearch_gradio.py

image-20240823233348375

我们打开gradio 自动创建的二级域名URL 地址https://6af4cab6a65b06dec6.gradio.live/

然后就可以即刻体验啦。

image-20240823233843831

使用硅基流动 API +无网络限制的DuckDuckGoSearch 搜索这样的AI 搜索还挺快的,哈哈。

4.部署到 HuggingFace Space

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

image-20240823230741946

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

image-20240823231025510

点击 create space

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

image-20240823231203792

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

image-20240823232547927

image-20240823232654848

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

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

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

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)

我们从huggingface 把我们的空项目下载下来

image-20240824002619317

回到Codespaces shell 命令行窗口中执行

cd /workspaces/codespaces-blank
# 下面的代码注意不能直接用把xxxx 换成你的token;  huggingface.co/spaces/zhouhui/mindsearch  换成你的项目URL
git clone https://zhouhui:xxxx@huggingface.co/spaces/zhouhui/mindsearch

image-20240824003814898

我们需要将上面mindsearch_deploy 文件下内 app.py requirements.txt 以及mindsearch 目录下的文件复制到/workspaces/codespaces-blank/mindsearch

cd /workspaces/mindsearch/mindsearch_deploy
cp app.py /workspaces/codespaces-blank/mindsearch
cp requirements.txt /workspaces/codespaces-blank/mindsearch
cp -r mindsearch/  /workspaces/codespaces-blank/mindsearch

image-20240824004304993

Then commit and push:

cd /workspaces/codespaces-blank/mindsearch
git init
git add .
git commit -m "Add application file"
# 下面的代码注意不能直接用把xxxx 换成你的token;  huggingface.co/spaces/zhouhui/mindsearch  换成你的项目URL 上面步骤有了,这步可以不用
#git remote set-url origin https://zhouhui:XXXXXXX@huggingface.co/spaces/zhouhui/mindsearch
git push origin

image-20240824145710074

我们打开huggingface space 上传的文件目录如下

image-20240824145835122

当运行成功后我们验证,打开https://huggingface.co/spaces/zhouhui/mindsearch 地址

image-20240824150325022

就可以测试了

image-20240824150520394

注意事项: 2023 年 10 月 1 日 开始Hugging Face不再接受密码作为命令行 Git 操作的认证方式,也就是通过账号和密码的方式是不能发访问的,否则会导致git 代码上传不了的问题。

参考文档https://huggingface.co/blog/zh/password-git-deprecation

5 .huggingface ssh设置(补充版本可以不看)

生成ssh的key 我们那本地电脑来做测试

ssh-keygen -t ed25519 -C "wwwzhouhui2024@gmail.com"

image-20240824100725274

这样你的windows平台上会通过ssh-agent 生成id_ed25519.pub 和id_ed25519

image-20240824100830226

windows 平台如果没有开启ssh-agent 导致上面没有创建成功 可以参考https://blog.csdn.net/m0_63969219/article/details/124650073

设置key存储的位置,打开https://huggingface.co/settings/profile,选择 SSH and GPG keys

image-20240824083733210

点击" add ssh key"

image-20240824083815840

打开文件,将文件中的key复制到hf中

image-20240824101009988

image-20240824085827655

image-20240824085858401

配置成功后,我们在本地电脑上

ssh -T git@hf.co

image-20240824101131280

看到这个说明我们本地电脑和huggingface ssh设置成功。

参考https://huggingface.co/docs/hub/security-git-ssh

参考文献

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2070152.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

uniapp检测手机是否打开定位权限Vue3-直接复制粘贴

安卓示例&#xff1a; 苹果示例&#xff1a; 代码实现&#xff08;vue3写法&#xff09;&#xff1a; const checkGPS ()>{console.log(开始监听GPS状态);let system uni.getSystemInfoSync(); // 获取系统信息if (system.platform android) { // 判断平台var context …

【数据中心小知识】电力需求如此重要,以至于数据中心通常以耗电量而非建筑面积来衡量

我们通常认为软件是完全数字化的存在&#xff0c;是一个完全独立于“原子”世界的“位”世界。我们可以在手机上下载无限量的数据&#xff0c;而手机却不会因此而变重&#xff1b;我们可以观看数百部电影而不用接触物理磁盘&#xff1b;我们可以收集数百本书而不需要拥有一张纸…

Comsol 考虑波导的二维星形空穴型声子晶体线缺陷压电能量收集优化方案

参考文献&#xff1a;Yang X , Zhong J , Xiang J .Optimization scheme for piezoelectric energy harvesting in line-defect for 2D starlike hole-type phononic crystals considering waveguides[J].AIP Advances, 2022, 12(1):-. 利用声子晶体(PnC)增强弹性波能收集是电…

SD差点挂掉,后备军们兴奋入场,AI生图应用正在爆发?

前后不到一个月&#xff0c;两个开源生图模型相继上线。 首先是由称得上 SD 原班人马的黑森林实验室推出的 FLUX.1。黑森林实验室由 Stable Diffusion 的核心开发者 Robin Rombach 领衔创立&#xff0c;团队成员基本上都是 Stable Diffusion 3 的作者&#xff0c;其中三名元老…

学习yolo+Java+opencv简单案例(二)

对于一些源码可以参考我上一篇博客&#xff1a;学习yoloJavaopencv简单案例&#xff08;一&#xff09;-CSDN博客 这篇文章主要演示的是使用面向对象优雅的实现图像识别&#xff1a; 也有接口演示&#xff0c;包括将Onnx对象放入Bean中程序跑起来就初始化一次&#xff08;重点…

AI产品经理的35岁危机_产品经理会有35岁危机吗

01 被裁的35岁朋友 去年&#xff0c;一家知名公司大裁员&#xff0c;很多 35 岁的非高管员工被牵连&#xff0c;包括我的一位朋友。 我第一时间联系了他&#xff0c;看看有没有能够帮上忙的地方。 我&#xff1a;传闻XX公司要收购你们&#xff1f; 朋友&#xff1a;是的。我要…

shell程序设计入门(二)

shell程序设计入门&#xff08;二&#xff09; 导语shell语法变量引号环境变量参数变量 条件控制结构if else循环forwhileuntil caseAND和ORANDOR 函数 总结参考文献 导语 shell语法 变量 shell变量和C语言的标识符命名的要求类似&#xff0c;在shell中&#xff0c;可以在变…

“易碎”的留守农村人,都在被AI智能监控“兜住”

文 | 智能相对论 作者 | 陈泊丞 “村里的四伯走了&#xff0c;是第二天傍晚被邻居家的七婶发现的。” 那晚&#xff0c;和家里的父母通电话&#xff0c;他们突然提起了这件事。 四伯虽说是父亲的堂兄弟&#xff0c;但是也只是辈分相当&#xff0c;在年纪上比父亲大上许多。…

零知识证明;Halo2原理;举例说明算术电路、转换为约束系统、多项式承诺举例形式和数值;PLANK算术化;

目录 零知识证明 简单举例说明原理 原理概述 Halo2原理 Halo2原理 举例说明关键性概念 举例说明算术电路、转换为约束系统、多项式承诺举例形式和数值 1. 算术电路构建 2. 转换为约束系统 3. 多项式承诺举例形式和数值 Halo2简单示例 PLANK算术化 基础概念 简单例…

如何维护好客户关系?

在这个信息爆炸、竞争激烈的市场环境中&#xff0c;每一位客户的信任与支持都是我们最宝贵的财富。 今天&#xff0c;就让我们一起探索那些温暖人心的秘诀&#xff0c;学习如何像匠人一样&#xff0c;精心维护与每一位客户的关系&#xff0c;让每一次互动都成为加深情感的桥梁。…

XTuner微调个人小助手认知

1. 环境准备 将Tutorial仓库的资料克隆到本地 mkdir -p /root/InternLM/Tutorial git clone -b camp3 https://github.com/InternLM/Tutorial /root/InternLM/Tutorial 创建一个叫做demo的虚拟环境 # 创建虚拟环境 conda create -n demo python3.10 -y# 激活虚拟环境&…

c#实现生成AES加密的密钥key(密钥长度128位,也就是32个字符)对标Java中的AES加密(SHA1PRNG+Hex.encodeHexString)

最近在做某省份的一个健康云平台检验结果互认&#xff0c;我们的系统用的是C#&#xff0c;里面要求生成一个AES加密的密钥key&#xff08;密钥长度128位&#xff0c;也就是32个字符&#xff09;&#xff0c;后面要用这个密钥key完成一系列加密操作&#xff0c;给的实例只有Java…

http应用层协议

一、万维网 用来存放各种资源的网络。 1、如何在万维网中表示一个资源 ? url ——统一资源定位符&#xff1b; 形式&#xff1a; <协议>://<主机>:<端口>/<路径>&#xff1b; <主机>:<端口>/<路径> //表示了资源所在的…

彩色墨水屏(电子纸)智能工牌,开启职场未来想象

随着技术的进步和生活方式的变革&#xff0c;越来越多职场人士希望佩戴的工牌能够展现独特的个人风格和专业特点&#xff0c;实现自动打卡、门禁管理等功能&#xff0c;提高工作效率&#xff0c;让职场生活更加便捷。 ​因此&#xff0c;快节奏的现代职场需一个既能满足员工对…

shadertoy sdSegment 原理

sdSegment 原理 float sdSegment( in vec2 p, in vec2 a, in vec2 b ) {vec2 pa p-a, ba b-a;float h clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );return length( pa - ba*h ); }原理: u ⃗ \vec{u} u 在 v ⃗ \vec{v} v 在夹角是 θ \theta θ 的投影长度是: &#xff…

HTML5休闲小游戏《猫猫咖啡店》源码,引流、刷广告利器

HTML5休闲小游戏《猫猫咖啡店》源码&#xff0c;直接把源码上传到服务器就能使用了&#xff01; 下载链接&#xff1a;https://www.huzhan.com/code/goods468502.html

vscode修改选中文字颜色及当前tab颜色

VSCode-》首选项-》设置->-》搜color&#xff0c;找到&#xff1a;Workbench&#xff1a;Color Customizations&#xff0c;点击&#xff1a;在 settings.json 中编辑 加上 选中的文字内容的 配置 "workbench.colorCustomizations": {//设置用户选中代码段的颜色&…

贪心+栈。。

前言&#xff1a;这个题目一开始我没想通的就是如果s当前的一个字符或者之后的一个字符和当前t的尾巴是一样的&#xff0c;那么优先选哪一个&#xff0c;其实这个就要优先选t的 class Solution { public:string robotWithString(string s) {string ans;int cnt[26]{}, min 0; …

2024年AI编程新手必备工具,快速提升技能!

在当今这个技术日新月异的时代&#xff0c;AI编程已成为一个越来越重要的领域&#xff0c;吸引着众多新手和希望提升自己的中级开发者进入。 对于这些渴望在AI领域快速成长的人来说&#xff0c;选择合适的编程工具是至关重要的。 接下来&#xff0c;我们将深入探讨几款市场上…

Ubuntu22.04下安装LDAP

目录 1 简单说明2 安装配置2.1 安装1、安装前准备2、安装 OpenLADP3、配置OpenLDAP4、设置基本组5、添加新组5、添加 OpenLDAP 用户 2.2 安装 LDAP 帐户管理器1、安装2、配置 LDAP 帐户管理器 3 简单使用3.1 创建一个组3.2 创建一个用户 总结 1 简单说明 之前写过在Centos下的…