当前位置: 首页 > news >正文

大模型WebUI:Gradio全解11——Chatbots:融合大模型的多模态聊天机器人(2)

大模型WebUI:Gradio全解11——Chatbots:融合大模型的聊天机器人(2)

  • 前言
  • 本篇摘要
  • 11. Chatbot:融合大模型的多模态聊天机器人
    • 11.2 使用流行的LLM库和API
      • 11.2.1 Llama Index
      • 11.2.2 LangChain
      • 11.2.3 OpenAI
        • 1. 基本用法
        • 2. 语音聊天
        • 3. Twilio凭据
        • 4. 自定义Interface
      • 11.2.4 Hugging Face transformers
      • 11.2.5 SambaNova
      • 11.2.6 Hyperbolic
      • 11.2.7 Anthropic Claude
    • 参考文献

前言

本系列文章主要介绍WEB界面工具Gradio。Gradio是Hugging Face发布的简易webui开发框架,它基于FastAPI和svelte,便于开发多功能界面和部署人工智能模型,是当前热门的非常易于开发和展示机器学习大语言模型LLM及扩散模型DM的UI框架。本系列文章分为前置概念和实战演练两部分。前置概念先介绍Gradio的详细技术架构、历史、应用场景、与其他框架Gradio/NiceGui/StreamLit/Dash/PyWebIO的区别,然后详细介绍了著名的资源网站Hugging Face,因为Gradio演示中经常用到Hugging Face的models及某些场景需要部署在spaces,这里包括三类资源models/datasets/spaces的使用、六类工具库transformers/diffusers/datasets/PEFT/accelerate/optimum实战。实战演练部分先讲解了多种不同的安装、运行和部署方式,安装包括Linux/Win/Mac三类系统安装,运行包括普通方式和热重载方式,部署包括本地部署、HuggingFace托管、FastAPI挂载和Gradio-Lite浏览器集成;然后按照先整体再细节的逻辑,讲解Gradio的多种高级特性,包括三种Gradio Clients(python/javascript/curl)、Gradio Tools、Gradio的模块架构和环境变量等,方便读者对Gradio整体把握;最后深入细节,也是本系列文章的核心,先实践基础功能Interface、Blocks和Additional Features,再详解高级功能Chatbots、Data Science And Plots和Streaming。本系列文章讲解细致,涵盖Gradio大部分组件和功能,代码均可运行并附有大量运行截图,方便读者理解,Gradio一定会成为每个技术人员实现奇思妙想的最称手工具。

本系列文章目录如下:

  1. 《Gradio全解1——Gradio简介》
  2. 《Gradio全解1——Gradio的安装与运行》
  3. 《Gradio全解2——剖析Hugging Face:详解三类资源models/datasets/spaces》
  4. 《Gradio全解3——剖析Hugging Face:实战六类工具库transformers/diffusers/datasets/PEFT/accelerate/optimum》
  5. 《Gradio全解4——Gradio的3+1种部署方式实践》
  6. 《Gradio全解4——浏览器集成Gradio-Lite》
  7. 《Gradio全解5——Gradio Client:python客户端》
  8. 《Gradio全解5——Gradio Client:javascript客户端》
  9. 《Gradio全解5——Gradio Client:curl客户端》
  10. 《Gradio全解6——Gradio Tools:将Gradio用于LLM Agents》
  11. 《Gradio全解7——Gradio库的模块架构和环境变量》
  12. 《Gradio全解8——Interface:高级抽象界面类(上)》
  13. 《Gradio全解8——Interface:高级抽象界面类(下)》
  14. 《Gradio全解9——Blocks:底层区块类(上)》
  15. 《Gradio全解9——Blocks:底层区块类(下)》
  16. 《Gradio全解10——Additional Features:补充特性(上)》
  17. 《Gradio全解10——Additional Features:补充特性(下)》
  18. 《Gradio全解11——Chatbot:融合大模型的多模态聊天机器人(上)》
  19. 《Gradio全解11——Chatbot:融合大模型的多模态聊天机器人(下)》
  20. 《Gradio全解系列12——Data Science And Plots:数据科学与绘图》
  21. 《Gradio全解13——Streaming:数据流(上)》
  22. 《Gradio全解13——Streaming:数据流(下)》

本篇摘要

本篇介绍如何使用Gradio创建聊天机器人,主要内容包括gr.ChatInterface快速创建Chatbot、与流行LLM库及API结合、使用Agents和Tools智能代理工具、使用Blocks创建Chatbot、Chatbot的特殊Events、通过Gradio应用创建Discord Bot/Slack Bot/Website Widget。

11. Chatbot:融合大模型的多模态聊天机器人

本章介绍如何使用Gradio创建聊天机器人。聊天机器人是大型语言模型(LLMs)的一个流行应用,通过Gradio,我们可以轻松构建LLM演示并与其它用户分享,或者自己使用直观的聊天机器人界面进行开发尝试。本章主要内容包括gr.ChatInterface快速创建Chatbot、与流行LLM库及API结合、使用Agents和Tools智能代理工具、使用Blocks创建Chatbot、Chatbot的特殊Events、通过Gradio应用创建Discord Bot/Slack Bot/Website Widget。

11.2 使用流行的LLM库和API

在本节中,我们将通过几个示例展示如何将gr.ChatInterface与流行的LLM库和API提供商一起使用,将涵盖以下库和API提供商:

  • Llama Index
  • LangChain
  • OpenAI
  • Hugging Face transformers
  • SambaNova
  • Hyperbolic
  • Anthropic’s Claude

大部分LLM库和提供商都存在社区维护的集成库,这使得启动Gradio应用程序更加容易。我们将在下面的适当部分中引用这些库,下面逐一介绍它们的用法。

11.2.1 Llama Index

让我们从在OpenAI上使用llama-index开始,构建一个RAG聊天机器人。该机器人可以在任意文本或 PDF文件上运行,并且可以在不到30行代码中演示和分享它。此示例需要OpenAI密钥(请继续阅读以获取免费的开源等效方案!),代码如下:

# This is a simple RAG chatbot built on top of Llama Index and Gradio. It allows you to upload any text or PDF files and ask questions about them!
# Before running this, make sure you have exported your OpenAI API key as an environment variable:
# export OPENAI_API_KEY="your-openai-api-key"from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
import gradio as grdef answer(message, history):files = []for msg in history:if msg['role'] == "user" and isinstance(msg['content'], tuple):files.append(msg['content'][0])for file in message["files"]:files.append(file)documents = SimpleDirectoryReader(input_files=files).load_data()index = VectorStoreIndex.from_documents(documents)query_engine = index.as_query_engine()return str(query_engine.query(message["text"]))demo = gr.ChatInterface(answer,type="messages",title="Llama Index RAG Chatbot",description="Upload any text or pdf files and ask questions about them!",textbox=gr.MultimodalTextbox(file_types=[".pdf", ".txt"]),multimodal=True
)demo.launch()

运行界面如下:
在这里插入图片描述
注意:

  1. 需要安装包llama_index,受限于未知原因,有些代码作者难以运行出结果,请读者将重点放在理解代码,下同;
  2. 如果未设置OPENAI_API_KEY,提交文档后,会在后台报错:Original error:No API key found for OpenAI。OPENAI_API_KEY获取地址:https://platform.openai.com/account/api-keys,使用OPENAI、Google或Microsoft注册账号登录后,创建某组织(可随意填写)并跳过邀请成员后,即可获得。然后在运行环境中键入命令:export OPENAI_API_KEY=“your-openai-api-key”;
  3. 如果设置后还遇到401认证错误,可能是因为OpenAI API客户端无法从环境变量中获取API令牌。此时可以将其保存到Python会话中,或者在代码界面运行:
import os
os.environ["OPENAI_API_KEY"] = ""

11.2.2 LangChain

以下是一个在OpenAI上使用langchain构建通用聊天机器人的示例。与之前一样,此示例需要OpenAI 密钥。

# This is a simple general-purpose chatbot built on top of LangChain and Gradio.
# Before running this, make sure you have exported your OpenAI API key as an environment variable:
# export OPENAI_API_KEY="your-openai-api-key"from langchain_openai import ChatOpenAI
from langchain.schema import AIMessage, HumanMessage
import gradio as grmodel = ChatOpenAI(model="gpt-4o-mini")def predict(message, history):history_langchain_format = []for msg in history:if msg['role'] == "user":history_langchain_format.append(HumanMessage(content=msg['content']))elif msg['role'] == "assistant":history_langchain_format.append(AIMessage(content=msg['content']))history_langchain_format.append(HumanMessage(content=message))gpt_response = model.invoke(history_langchain_format)return gpt_response.contentdemo = gr.ChatInterface(predict,type="messages"
)demo.launch()

运行界面如下:
在这里插入图片描述
提示:本例需安装langchain_openai和langchain。另外,对于快速原型设计,社区维护的langchain-gradio仓库使得在LangChain上构建聊天机器人变得更加容易。

11.2.3 OpenAI

当然我们也可以直接使用openai库,但对于快速原型设计,openai-gradio库使得在OpenAI模型上构建聊天机器人更加容易。openai-gradio是一个 Python包,它使开发者能够非常轻松地创建由OpenAI API驱动的机器学习应用程序。

1. 基本用法

使用以下命令安装openai-gradio:

pip install openai-gradio

同样需要设置OPENAI_API_KEY,然后就可以通过几行代码完成聊天机器人程序:

import gradio as gr
import openai_gradiogr.load(name='gpt-4-turbo',src=openai_gradio.registry,
).launch()

运行后就可以看到连接到OpenAI模型的Gradio界面:
在这里插入图片描述
底层原理:openai-gradio Python库有两个依赖项:openai和gradio,它定义了一个“注册”函数 openai_gradio.registry,该函数接收一个模型名称并返回一个Gradio应用。

2. 语音聊天

OpenAI-Gradio还支持语音聊天功能。我们可以通过以下两种方式启用该功能:

  1. 使用实时模型:
import gradio as gr
import openai_gradiogr.load(name='gpt-4o-realtime-preview-2024-10-01',src=openai_gradio.registry
).launch()
  1. 显式地使用任意实时模型:
import gradio as gr
import openai_gradiogr.load(name='gpt-4o-mini-realtime-preview-2024-12-17',src=openai_gradio.registry,enable_voice=True
).launch()

这将创建一个基于WebRTC的界面,允许与AI模型进行实时语音对话。

3. Twilio凭据

为了实现语音聊天功能,除了OPENAI_API_KEY,还需要Twilio凭据(WebRTC语音聊天所需):

export TWILIO_ACCOUNT_SID=<your Twilio account SID>
export TWILIO_AUTH_TOKEN=<your Twilio auth token>

我们可以通过以下方式获取Twilio的凭证:

  1. 在 Twilio 上创建一个免费账户,地址:https://www.twilio.com/en-us;
  2. 在 Twilio 控制台中获取 Account SID 和 Auth Token。
    如果没有Twilio凭证,语音聊天功能仍然可以工作,但在某些网络环境中可能会遇到连接问题。
4. 自定义Interface

一旦我们可以通过OpenAI端点创建一个Gradio用户界面,就可以通过设置自己的输入和输出组件或任何其他gr.Interface参数来自定义它。演示代码如下:

import gradio as gr
import openai_gradiogr.load(name='gpt-4-turbo',src=openai_gradio.registry,title='OpenAI-Gradio Integration',description="Chat with GPT-4-turbo model.",examples=["Explain quantum gravity to a 5-year old.", "How many R are there in the word Strawberry?"]
).launch()

运行截图如下:
在这里插入图片描述
或者将加载的Interface组合到更大的Gradio Web用户界面中,例如:

import gradio as gr
import openai_gradiowith gr.Blocks() as demo:with gr.Tab("GPT-4-turbo"):gr.load('gpt-4-turbo', src=openai_gradio.registry)with gr.Tab("GPT-3.5-turbo"):gr.load('gpt-3.5-turbo', src=openai_gradio.registry)demo.launch()

OpenAI支持的所有聊天API模型都与该集成兼容。有关可用模型及其详细信息的完整列表,请参阅 OpenAI模型文档:https://platform.openai.com/docs/models。

11.2.4 Hugging Face transformers

在许多情况下,我们可能希望在本地运行聊天机器人。以下是使用Hugging Face transformers库和 SmolLM2-135M-Instruct模型的等效示例:

from transformers import AutoModelForCausalLM, AutoTokenizer
import gradio as grcheckpoint = "HuggingFaceTB/SmolLM2-135M-Instruct"
device = "cpu"  # "cuda" or "cpu"
tokenizer = AutoTokenizer.from_pretrained(checkpoint)
model = AutoModelForCausalLM.from_pretrained(checkpoint).to(device)def predict(message, history):history.append({"role": "user", "content": message})input_text = tokenizer.apply_chat_template(history, tokenize=False)inputs = tokenizer.encode(input_text, return_tensors="pt").to(device)  outputs = model.generate(inputs, max_new_tokens=100, temperature=0.2, top_p=0.9, do_sample=True)decoded = tokenizer.decode(outputs[0])response = decoded.split("<|im_start|>assistant\n")[-1].split("<|im_end|>")[0]return responsedemo = gr.ChatInterface(predict, type="messages")demo.launch()

运行截图如下:

11.2.5 SambaNova

SambaNova Cloud API提供了对全精度开源模型(例如Llama系列)的访问权限。以下是一个围绕SambaNova API构建Gradio应用的示例(注意这里需要设置SAMBANOVA_API_KEY,申请地址:https://sambanova.ai/):

# This is a simple general-purpose chatbot built on top of SambaNova API. 
# Before running this, make sure you have exported your SambaNova API key as an environment variable:
# export SAMBANOVA_API_KEY="your-sambanova-api-key"import os
import gradio as gr
from openai import OpenAIapi_key = os.getenv("SAMBANOVA_API_KEY")client = OpenAI(base_url="https://api.sambanova.ai/v1/",api_key=api_key,
)def predict(message, history):history.append({"role": "user", "content": message})stream = client.chat.completions.create(messages=history, model="Meta-Llama-3.1-70B-Instruct-8k", stream=True)chunks = []for chunk in stream:chunks.append(chunk.choices[0].delta.content or "")yield "".join(chunks)demo = gr.ChatInterface(predict, type="messages")demo.launch()

提示:对于快速原型设计,sambanova-gradio库使得在SambaNova模型上构建聊天机器人变得更加容易。

11.2.6 Hyperbolic

Hyperbolic AI API提供了对许多开源模型(例如Llama系列)的访问权限。以下是一个通过SambaNova API构建Gradio应用的示例(这里同样需要设置HYPERBOLIC_API_KEY):

# This is a simple general-purpose chatbot built on top of Hyperbolic API. 
# Before running this, make sure you have exported your Hyperbolic API key as an environment variable:
# export HYPERBOLIC_API_KEY="your-hyperbolic-api-key"import os
import gradio as gr
from openai import OpenAIapi_key = os.getenv("HYPERBOLIC_API_KEY")client = OpenAI(base_url="https://api.hyperbolic.xyz/v1/",api_key=api_key,
)def predict(message, history):history.append({"role": "user", "content": message})stream = client.chat.completions.create(messages=history, model="gpt-4o-mini", stream=True)chunks = []for chunk in stream:chunks.append(chunk.choices[0].delta.content or "")yield "".join(chunks)demo = gr.ChatInterface(predict, type="messages")demo.launch()

提示:对于快速原型设计,hyperbolic-gradio库使得在Hyperbolic模型上构建聊天机器人变得更加容易。

11.2.7 Anthropic Claude

Anthropic的Claude模型也可以通过API使用。以下是一个基于Anthropic API构建的简单20个问题风格的游戏示例:

# This is a simple 20 questions-style game built on top of the Anthropic API.
# Before running this, make sure you have exported your Anthropic API key as an environment variable:
# export ANTHROPIC_API_KEY="your-anthropic-api-key"import anthropic
import gradio as grclient = anthropic.Anthropic()def predict(message, history):keys_to_keep = ["role", "content"]history = [{k: d[k] for k in keys_to_keep if k in d} for d in history]history.append({"role": "user", "content": message})if len(history) > 20:history.append({"role": "user", "content": "DONE"})output = client.messages.create(messages=history,  model="claude-3-5-sonnet-20241022",max_tokens=1000,system="You are guessing an object that the user is thinking of. You can ask 10 yes/no questions. Keep asking questions until the user says DONE")return {"role": "assistant","content": output.content[0].text,  "options": [{"value": "Yes"}, {"value": "No"}]}placeholder = """
<center><h1>10 Questions</h1><br>Think of a person, place, or thing. I'll ask you 10 yes/no questions to try and guess it.
</center>
"""demo = gr.ChatInterface(predict,examples=["Start!"],chatbot=gr.Chatbot(placeholder=placeholder),type="messages"
)demo.launch()

参考文献

  1. Gradio - guides - Additional Features
  2. openai-gradio

相关文章:

大模型WebUI:Gradio全解11——Chatbots:融合大模型的多模态聊天机器人(2)

大模型WebUI&#xff1a;Gradio全解11——Chatbots&#xff1a;融合大模型的聊天机器人&#xff08;2&#xff09; 前言本篇摘要11. Chatbot&#xff1a;融合大模型的多模态聊天机器人11.2 使用流行的LLM库和API11.2.1 Llama Index11.2.2 LangChain11.2.3 OpenAI1. 基本用法2. …...

课题推荐——基于GPS的无人机自主着陆系统设计

关于“基于GPS的无人机自主着陆系统设计”的详细展开&#xff0c;包括项目背景、具体内容、实施步骤和创新点。如需帮助&#xff0c;或有导航、定位滤波相关的代码定制需求&#xff0c;请点击文末卡片联系作者 文章目录 项目背景具体内容实施步骤相关例程MATLAB例程python例程 …...

HQChart使用教程30-K线图如何对接第3方数据44-DRAWPIE数据结构

HQChart使用教程30-K线图如何对接第3方数据44-DRAWPIE数据结构 效果图DRAWPIEHQChart代码地址后台数据对接说明示例数据数据结构说明效果图 DRAWPIE DRAWPIE是hqchart插件独有的绘制饼图函数,可以通过麦语法脚本来绘制一个简单的饼图数据。 饼图显示的位置固定在右上角。 下…...

张朝阳惊现CES展,为中国品牌 “代言”的同时,或将布局搜狐新战略!

每年年初&#xff0c;科技圈的目光都会聚焦在美国拉斯维加斯&#xff0c;因为这里将上演一场被誉为 “科技春晚” 的年度大戏 ——CES 国际消费电子展。作为全球规模最大、最具影响力的科技展会之一&#xff0c;CES 吸引了来自 160 多个国家的创新者和行业领导者&#xff0c;是…...

堆排序+选择排序详解

目录 1.选择排序的定义 2.选择排序的优缺点 2.1优点 2.2缺点 3.思考 4.优化后的选择排序的实现 5.选择排序的代码 6.堆排序 7.向上/向下调整算法 8. 向下向上调整代码 9.堆排序代码 1.选择排序的定义 选择排序(SelectSort)&#xff0c;以第一个为开始值&#xff0c…...

【Arthas命令实践】heapdump实现原理

&#x1f3ae; 作者主页&#xff1a;点击 &#x1f381; 完整专栏和代码&#xff1a;点击 &#x1f3e1; 博客主页&#xff1a;点击 文章目录 使用原理 使用 dump java heap, 类似 jmap 命令的 heap dump 功能。 【dump 到指定文件】 heapdump arthas-output/dump.hprof【只 …...

python-leetcode-判断子序列

392. 判断子序列 - 力扣&#xff08;LeetCode&#xff09; class Solution:def isSubsequence(self, s: str, t: str) -> bool:i, j 0, 0 # i 指向 s&#xff0c;j 指向 twhile i < len(s) and j < len(t):if s[i] t[j]:i 1j 1return i len(s)...

【Verdi实用技巧-Part2】

Verdi实用技巧-Part2 2 Verdi实用技巧-Part22.1 Dump波形常用的task2.1.1 Frequently Used Dump Tasks2.1.2 Demo 2.2 提取波形信息小工具--FSDB Utilities2.3 Debug in Source code view2.3.1 Find Scopes By Find Scope form 2.3.2 Go to line in Souce code View2.3.3 Use B…...

常用的AT命令,用于查看不同类型的网络信息

文章目录 1. ATCSQ‌&#xff1a;2. ATCREG‌&#xff1a;‌3. ATCOPS‌&#xff1a;4. ATCGATT‌&#xff1a;5. ATCGPADDR‌&#xff1a; 在AT命令集中&#xff0c;用于查看网络信息的命令有多种&#xff0c;具体取决于所使用的设备和模块。以下是一些常用的AT命令&#xff0…...

【应用篇】09.实现简易的Shell命令行解释器

一、shell和bash的关系 shell是命令解释器&#xff0c;它接收用户的命令并将其传递给内核去执行。bash,即GNU Bourne-Again Shell&#xff0c;是shell的一种实现方式&#xff0c;也是大多数linux系统下默认的shell。 bash的原理 大多数的指令进程&#xff08;除了内建命令&…...

负载均衡技术【内网去外网运营商出口负载均衡】

1 负载均衡概述 LB&#xff08;Load Balance&#xff0c;负载均衡&#xff09;是一种集群技术&#xff0c;它将特定的业务&#xff08;网络服务、网络流量等&#xff09;分担给多台网络设备&#xff08;包括服务器、防火墙等&#xff09;或多条链路&#xff0c;从而提高了业务…...

【广西乡镇界】arcgis格式shp数据乡镇名称和编码2020年内容测评

【广西乡镇界】arcgis格式shp数据乡镇名称和编码2020年内容测评...

半导体数据分析: 玩转WM-811K Wafermap 数据集(一) AI 机器学习

在半导体行业&#xff0c;工程师依靠 CP Yield&#xff08;生产过程中芯片的合格率&#xff09;、WAT&#xff08;晶圆验收测试&#xff09;和 Particle 的晶圆图模式来识别工艺问题。然而&#xff0c;在没有人工干预的情况下将这些晶圆图模式分类是一项重大挑战。许多论文都研…...

mongodb安装并设置用户验证登录

下载地址 https://www.mongodb.com/try/download/community-kubernetes-operator 偶数版是稳定版&#xff0c;基数版是开发版 &#xff0c;对32位支持不好 --------------------------------CentOS下安装mongodb--------------------------------------------------- 解压安装包…...

《零基础Go语言算法实战》【题目 1-16】字符串的遍历与比较

《零基础Go语言算法实战》 【题目 1-16】字符串的遍历与比较 给出两个字符串&#xff0c;请编写程序以确定能否将其中一个字符串重新排列后变成另一个字符串&#xff0c; 并规定大小写是不同的字符&#xff0c;空格也作为字符考虑。保证两个字符串的长度小于或等于 5000。 …...

VUE3封装一个Hook

在 Vue 3 中&#xff0c;Composition API 让我们能够封装和复用代码逻辑&#xff0c;尤其是通过 setup 函数进行组件间的复用。为了提高代码的可复用性&#xff0c;我们可以把一些常见的 API 请求和状态管理逻辑封装到一个单独的 hook 中。 以下是一个简单的例子&#xff0c;我…...

【Linux】Linux常见指令(上)

个人主页~ 初识Linux 一、Linux基本命令1、ls指令2、pwd命令3、cd指令4、touch指令5、mkdir指令6、rmdir指令7、rm指令8、man指令9、cp指令10、mv命令 Linux是一个开源的、稳定的、安全的、灵活的操作系统&#xff0c;Linux下的操作都是通过指令来实现的 一、Linux基本命令 先…...

嵌入式 C 语言:一维数组

目录 一、定义 二、内存布局 三、数组的初始化 3.1. 完全初始化 3.2. 部分初始化 3.3. 不指定大小初始化 四、使用数组 4.1. 访问数组元素 4.1.1. 通过索引访问数组元素 4.1.2. 通过指针访问数组元素 4.2. 遍历数组 4.3. 数组作为函数参数 五、应用场景 5.1. 数据…...

NineData云原生智能数据管理平台新功能发布|2024年12月版

本月发布 7 项更新&#xff0c;其中重点发布 2 项、功能优化 5 项。 重点发布 数据库 Devops - Oracle 非表对象支持可视化创建与管理 Oracle 非表对象&#xff0c;包括视图&#xff08;View&#xff09;、包&#xff08;Package&#xff09;、存储过程&#xff08;Procedur…...

iOS - 自旋锁

在 Objective-C 运行时中大量使用自旋锁&#xff0c;主要有以下几个原因&#xff1a; 1. 性能考虑 上下文切换成本 // 自旋锁实现 static ALWAYS_INLINE void OSSpinLockLock(volatile OSSpinLock *lock) {do {while (lock->value ! 0) {__asm__ volatile ("pause&q…...

域名备案页面模板

域名备案模板&#xff0c;首页底下正中央位置需要有备案号。 主要是给不太擅长于前端样式的人提供一个备案模板&#xff0c;直接把这个H5放到nginx的index.html就可以访问了 <html><body><div class"login-container"><h2>登录</h2>&…...

【socketioxide和axum集成-实现websocket实时通信-Rust点滴】

socketioxide的axum集成 启动socketio依靠examle里的layer一. 使用可变State依靠axum里的example二.提取client,IP1. 非代理,tcp,socket对方地址2.代理情况下socket.req_parts. 三. axum的handle中使用emit发送消息.1. io,存入State解决.2.把io存入初始设定作为唯一单例3.http-…...

计算机网络(第8版)第3章--PPP课后习题

【3-09】 一 个PPP 帧的数据部分(用十六进制写出)是7 D 5EFE 277D 5D7D 5D657D 5E。 试问真正的数据是什么(用十六进制写出)? 解答&#xff1a;把由转义符7D开始的2字节序列用下画线标出&#xff1a; 7D 5E FE 27 7D 5D 7D 5D 65 7D 5E 7D 5E应当还原成为7E。 7D5D 应…...

通过Android Studio修改第三方jar包并重新生成jar包

最近接手了来自公司其他同事的一个Unity项目,里面有一个封装的jar包要改动一下,无奈关于这个jar包的原工程文件丢失了,于是自己动手来修改下jar包,并做下记录。 一、导入第三方jar包 1、新建项目EditJarDemo(项目名随便取) 2、新建libs文件夹,把你要修改的third.jar 复制…...

Rabbitmq 业务异常与未手动确认场景及解决方案

消费端消费异常&#xff0c;业务异常 与 未手动确认是不是一个场景&#xff0c;因为执行完业务逻辑&#xff0c;再确认。解决方案就一个&#xff0c;就是重试一定次数&#xff0c;然后加入死信队列。还有就是消费重新放入队列&#xff0c;然后重新投递给其他消费者&#xff0c;…...

3D机器视觉的类型、应用和未来趋势

3D相机正在推动机器视觉市场的增长。很多制造企业开始转向自动化3D料箱拣选&#xff0c;专注于使用3D视觉和人工智能等先进技术来简化操作并减少开支。 预计3D相机将在未来五年内推动全球机器视觉市场&#xff0c;这得益于移动机器人和机器人拣选的强劲增长。到 2028 年&#…...

LabVIEW在反馈控制时如何解决带约束的控制问题

在LabVIEW中&#xff0c;解决带约束的反馈控制问题通常需要使用先进的控制算法或特定的方法来满足约束条件&#xff0c;同时保证控制系统的性能和稳定性。以下是解决这类问题的一些常用方法和步骤&#xff1a; ​ 1. 定义控制问题及约束条件 确定被控对象的动态特性&#xff08…...

PHP 在 2025 年的现状与展望

PHP 在 2025 年依然强劲&#xff0c;继续为超过 77% 使用已知服务器端编程语言的网站提供动力。这并非仅仅依靠遗留代码&#xff0c;像 WordPress、Shopify 和 Laravel 这样的主流平台持续推动 PHP 的发展&#xff0c;使其保持着 актуальность 并不断进化。 为什么…...

QT c++ 自定义按钮类 加载图片 美化按钮

如果你有需要利用图片美化按钮的情况&#xff0c;本文能帮助你。 鼠标左键按下按钮和松开&#xff0c;按钮显示不同的图片。 1.按钮类 //因为此类比较简单&#xff0c;1个头文件搞定&#xff0c;没有cpp文件 #ifndef CUSTOMBUTTON_H #define CUSTOMBUTTON_H #include <Q…...

夯实前端基础之HTML篇

知识点概览 HTML部分 1. DOM和BOM有什么区别&#xff1f; DOM&#xff08;Document Object Model&#xff09; 当网页被加载时&#xff0c;浏览器会创建页面的对象文档模型&#xff0c;HTML DOM 模型被结构化为对象树 用途&#xff1a; 主要用于网页内容的动态修改和交互&…...

pytest 参数介绍

命令行参数描述常见使用案例-v / --verbose显示每个测试用例的详细信息&#xff0c;包括测试名称和状态pytest -v-s / --captureno禁用输出捕获&#xff0c;允许 print() 输出显示pytest -s-q / --quiet安静模式&#xff0c;减少输出&#xff0c;仅显示每个测试的通过/失败结果…...

蓝桥杯训练

1对于一个字母矩阵&#xff0c;我们称矩阵中的一个递增序列是指在矩阵中找到两个字母&#xff0c;它们在同一行&#xff0c;同一列&#xff0c;或者在同一 45 度的斜线上&#xff0c;这两个字母从左向右看、或者从上向下看是递增的。 例如&#xff0c;如下矩阵中 LANN QIAO有…...

maven的简单介绍

目录 1、maven简介2、maven 的主要特点3、maven的下载与安装4、修改配置文件5、私服(拓展) 1、maven简介 Maven 是一个广泛使用的项目管理和构建工具&#xff0c;主要应用于 Java 项目。Maven 由 Apache 软件基金会开发和维护&#xff0c;它提供了一种简洁且一致的方法来构建、…...

超完整Docker学习记录,Docker常用命令详解

前言 关于国内拉取不到docker镜像的问题&#xff0c;可以利用Github Action将需要的镜像转存到阿里云私有仓库&#xff0c;然后再通过阿里云私有仓库去拉取就可以了。 参考项目地址&#xff1a;使用Github Action将国外的Docker镜像转存到阿里云私有仓库 一、Docker简介 Do…...

Kafka优势剖析-消费者组、并行消费

目录 1. 消费者组&#xff08;Consumer Group&#xff09; 1.1 什么是消费者组&#xff1f; 1.2 消费者组的工作原理 1.3 消费者组的优势 2. 并行消费&#xff08;Parallel Consumption&#xff09; 2.1 什么是并行消费&#xff1f; 2.2 并行消费的工作原理 2.3 并行消…...

MATLAB语言的多线程编程

MATLAB语言的多线程编程 引言 随着计算机技术的不断发展&#xff0c;尤其是在大数据和高性能计算领域&#xff0c;多线程编程逐渐成为一种重要的编程范式。MATLAB作为一种广泛应用于科学计算和工程模拟的高级编程语言&#xff0c;其强大的数学计算功能和丰富的工具箱&#xf…...

强化学习入门

RL学习路径 理解DQN原理 理解 标准版的策略梯度算法(Vanilla Policy Gradient) 模仿学习实践 Actor-Critic原理 从大模型机器人到imitation Learning与diffusion policy、ACT(Action Chunking with Transformers)的关系 大模型与机器人 tmp: 强化学习中的优势函数&#…...

Unity 2d描边基于SpriteRender,高性能的描边解决方案

目标 以Unity默认渲染管线为例&#xff0c;打造不需要图片内边距&#xff0c;描边平滑&#xff0c;高性能的描边解决方案 前言 在2d游戏中经常需要给2d对象添加描边&#xff0c;来突出强调2d对象 当你去网上查找2d描边shader&#xff0c;移植到项目里面&#xff0c;大概率会…...

2025第2周 | JavaScript中的Symbol

目录 1. Symbol是个什么东东&#xff1f;1.1 语法 2. 为什么需要Symbol?3. 怎么使用Symbol?3.1 定义对象字面量3.2 新增对象属性3.3 使用 Object.defineProperty方式3.4 遍历 4. 静态方法4.1 Symbol.for(key)4.2 Symbol.keyFor(symbol) 2025&#xff0c;做想做的事&#xff0…...

Unity学习之UGUI进阶

一、事件监听接口 1、作用 用于实现类型长按、双击、拖拽等基础控件无法实现的功能 所有控件都能够添加更多的事件监听来处理对应的逻辑 2、事件监听接口类型 &#xff08;1&#xff09;常用事件接口 &#xff08;2&#xff09;不常用事件接口 3、使用事件监听接口 &#…...

IT面试求职系列主题-Jenkins

想成功求职&#xff0c;必要的IT技能一样不能少&#xff0c;先说说Jenkins的必会知识吧。 1) 什么是Jenkins Jenkins 是一个用 Java 编写的开源持续集成工具。它跟踪版本控制系统&#xff0c;并在发生更改时启动和监视构建系统。 2&#xff09;Maven、Ant和Jenkins有什么区别…...

Allure 集成 pytest

Allure 是一个强大的测试报告工具&#xff0c;与 pytest 集成可以生成详细的测试报告&#xff0c;包括测试步骤、测试数据、截图、错误堆栈等。 1. 安装 Allure 和相关依赖 安装 pytest-allure-adaptor 插件&#xff1a; pip install allure-pytest确保本地已安装 Allure 工具。…...

Redis高频知识点

Redis 目录 1 Redis是AP的还是CP的&#xff1f;2 介绍一下Redis的集群方案&#xff1f;3 什么是Redis的数据分片&#xff1f;4 Redis为什么这么快&#xff1f;5 Redis 的事务机制是怎样的&#xff1f;7 Redis的持久化机制是怎样的&#xff1f;8 Redis 的过期策略是怎么样的&a…...

【电子通识】PWM驱动让有刷直流电机恒流工作

电机的典型驱动方法包括电压驱动、电流驱动以及PWM驱动。本文将介绍采用PWM驱动方式的恒流工作。 首先介绍的是什么是PWM驱动的电机恒流工作&#xff0c;其次是PWM驱动电机恒流工作时电路的工作原理。 PWM驱动 当以恒定的电流驱动电机时&#xff0c;电机会怎样工作呢&#xff1…...

PyMysql 02|(包含项目实战)数据库工具类封装

目录 七、数据库工具类封装 1、封装的目的 2、设计数据库工具类 3、实现类方法 1️⃣获取、关闭连接 2️⃣查询一条记录 3️⃣增删改数据 4️⃣完整封装代码实现 七、数据库工具类封装 1、封装的目的 将常用的数据库操作&#xff0c;封装到一个方法。 后续再操作数据…...

Pixel 6a手机提示无法连接移动网络,打电话失败!

1、开启VoLTE 2、如果没有&#xff0c;下载shizuku和PixelIMS应用。 shizuke Releases RikkaApps/Shizuku GitHub PixellMS Release v1.2.8 kyujin-cho/pixel-volte-patch GitHub 3、安装shizuke启动&#xff0c;开通root可以直接点击下面的启动&#xff0c;如果没有就…...

ubuntu20.04 在线安装postgresql 扩展postgis

基础配置 /etc/apt/sources.list # 添加pg官方基础配置deb http://apt.postgresql.org/pub/repos/apt/ focal-pgdg main# 添加ubuntu官方依赖&#xff08;防止下载依赖错误&#xff09;deb http://archive.ubuntu.com/ubuntu/ focal main restricted universe multiverse de…...

fitz获取pdf内容

1.获取pdf单页&#xff0c;及所有内容 import fitz # PyMuPDF# 打开 PDF 文件 pdf_path r"/data2/ljsang/0106/0725_Self-organization-of-plasticity-and-specialization-in-a-primi_2022_Cell-Syst.pdfπσΣ╕╖σσ║Θ║∩╝Φ╛τ▒│σ¡τ╛π.pdf" d…...

LabVIEW软件Bug的定义与修改

在LabVIEW软件开发过程中&#xff0c;bug&#xff08;程序错误或缺陷&#xff09;指的是程序中导致不符合预期行为的任何问题。Bug可能是由于编码错误、逻辑漏洞、硬件兼容性问题、系统资源限制等因素引起的。它可能会导致程序崩溃、功能无法正常执行或输出结果不符合预期。理解…...

Vue3(elementPlus) el-table替换/隐藏行箭头,点击整行展开

element文档链接&#xff1a; https://element-plus.org/zh-CN/component/form.html 一、el-table表格行展开关闭箭头替换成加减号 注&#xff1a;Vue3在样式中修改箭头图标无效&#xff0c;可能我设置不对&#xff0c;欢迎各位来交流指导 转变思路&#xff1a;隐藏箭头&…...