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

【Qwen-Audio部署实战】Qwen-Audio-Chat模型之对话机器人部署测试

系列篇章💥

No.文章
1【Qwen部署实战】探索Qwen-7B-Chat:阿里云大型语言模型的对话实践
2【Qwen2部署实战】Qwen2初体验:用Transformers打造智能聊天机器人
3【Qwen2部署实战】探索Qwen2-7B:通过FastApi框架实现API的部署与调用
4【Qwen2部署实战】Ollama上的Qwen2-7B:一键部署大型语言模型指南
5【Qwen2部署实战】llama.cpp:一键部署高效运行Qwen2-7B模型
6【Qwen2部署实战】部署高效AI模型:使用vLLM进行Qwen2-7B模型推理
7【AI大模型Agent探索】Qwen-Agent:基于Qwen的LLM应用开发框架
8【AI大模型Agent探索】深入探索实践 Qwen-Agent 的 Function Calling
9【AI大模型Agent探索】Qwen-Agent之RAG智能助手实践
10【RAG检索增强生成】LlamaIndex与Qwen2的高效检索增强生成实践
11【Qwen2微调实战】Lora微调Qwen2-7B-Instruct实践指南
12【Qwen2微调实战】LLaMA-Factory框架对Qwen2-7B模型的微调实践
13【Qwen-Audio部署实战】Qwen-Audio-Chat模型之FastApi部署实战
14【Qwen-Audio部署实战】Qwen-Audio-Chat模型之对话机器人部署测试

目录

  • 系列篇章💥
  • 引言
  • 一、环境准备
  • 二、安装依赖
    • 1、升级pip并更换源
    • 2、安装基础依赖包
    • 3、安装特定工具包及版本
    • 4、安装ffmpeg
  • 三、模型下载
    • 1、模型下载准备
    • 2、模型下载执行
  • 四、对话聊天机器人代码准备
  • 五、对话聊天机器人运行实践
    • 1、修改默认端口
    • 2、启动运行web chat机器人
    • 3、端口代理映射
    • 4、访问web聊天对话界面
    • 5、普通对话聊天
    • 6、音频文件识别
  • 结语


引言

在自然语言处理的浩瀚星海中,Qwen-Audio-Chat 模型以其卓越的性能和创新性,犹如一颗冉冉升起的新星,照亮了智能对话技术的前行之路。它不仅代表着对话系统的前沿发展,更是为实现自然、流畅且富有洞察力的交流体验提供了坚实的技术基础。本文将带领读者深入探讨 Qwen-Audio-Chat 模型的部署与测试流程,揭示其背后的技术奥秘,共同踏上这段充满挑战与创新的技术探索之旅。我们将重点介绍如何在 web 端构建并测试一个基于 Qwen-Audio-Chat 模型的对话机器人。

一、环境准备

在开始我们的技术之旅之前,确保拥有一个稳定而强大的运行环境是至关重要的。为此,可以在 autodl 平台上租赁一台性能卓越的服务器,该服务器应配备至少 24GB 的显存,例如 NVIDIA 的 RTX 3090 显卡,以满足模型训练和推理过程中对计算资源的高需求。

在镜像的选择上,我们建议采用 PyTorch-2.0.0 作为基础框架,并搭配 Python 3.8 环境(基于 Ubuntu 20.04 系统),同时推荐使用 CUDA 11.8 版本(至少 11.3 版本)以确保与 PyTorch 的兼容性和性能优化。完成服务器的租赁后,您可以通过 JupyterLab 图形界面快速访问服务器,并在其终端中进行环境配置、模型下载以及运行演示等关键步骤。
在这里插入图片描述

二、安装依赖

在终端中,我们需要执行一系列命令来完成 pip 换源以及相关依赖包的安装。为了确保顺利完成这些步骤,请按照以下指令操作。

1、升级pip并更换源

# 升级pip
python -m pip install --upgrade pip
# 更换 pypi 源加速库的安装
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

2、安装基础依赖包

# 安装常用的科学计算和机器学习库
pip install scipy torchvision pillow tensorboard matplotlib

3、安装特定工具包及版本

# 安装模型管理和优化相关的包
pip install modelscope==1.9.5 accelerate tiktoken einops transformers_stream_generator==0.0.4
# 安装较新版本的Transformers 和 gradio 库以支持AI大模型的部署
pip install transformers==4.32.0 gradio==3.39.0 nest_asyncio

4、安装ffmpeg

打开终端,输入以下命令安装ffmpeg:

sudo apt update
sudo apt install ffmpeg

通过以上步骤,您可以顺利更新pip、更换为更快的软件源,并安装所需的Python包和库,为您的Python开发环境做好准备。

三、模型下载

1、模型下载准备

使用 modelscope 中的snapshot_download函数下载模型,第一个参数为模型名称,参数cache_dir为模型的下载路径。
在 /root/autodl-tmp 路径下新建 d.py 文件并在其中输入以下内容

import torchfrom modelscope import snapshot_download, AutoModel, AutoTokenizerfrom modelscope import GenerationConfigmodel_dir = snapshot_download('qwen/Qwen-Audio-Chat', cache_dir='/root/autodl-tmp', revision='master')

在这里插入图片描述

2、模型下载执行

运行 python /root/autodl-tmp/d.py 执行下载,模型大小为 20 GB,下载模型大概需要10~20分钟
在这里插入图片描述

四、对话聊天机器人代码准备

在/root/autodl-tmp路径下新建web_demo_audio.py 文件并在其中输入以下内容:

# Copyright (c) Alibaba Cloud.
#
# This source code is licensed under the license found in the
# LICENSE file in the root directory of this source tree."""A simple web interactive chat demo based on gradio."""from argparse import ArgumentParser
from pathlib import Pathimport copy
import gradio as gr
import os
import re
import secrets
import tempfile
from transformers import AutoModelForCausalLM, AutoTokenizer
from transformers.generation import GenerationConfig
from pydub import AudioSegment#DEFAULT_CKPT_PATH = 'Qwen/Qwen-Audio-Chat'
DEFAULT_CKPT_PATH = "/root/autodl-tmp/qwen/Qwen-Audio-Chat"def _get_args():parser = ArgumentParser()parser.add_argument("-c", "--checkpoint-path", type=str, default=DEFAULT_CKPT_PATH,help="Checkpoint name or path, default to %(default)r")parser.add_argument("--cpu-only", action="store_true", help="Run demo with CPU only")parser.add_argument("--share", action="store_true", default=False,help="Create a publicly shareable link for the interface.")parser.add_argument("--inbrowser", action="store_true", default=False,help="Automatically launch the interface in a new tab on the default browser.")parser.add_argument("--server-port", type=int, default=6006,help="Demo server port.")parser.add_argument("--server-name", type=str, default="127.0.0.1",help="Demo server name.")args = parser.parse_args()return argsdef _load_model_tokenizer(args):tokenizer = AutoTokenizer.from_pretrained(args.checkpoint_path, trust_remote_code=True, resume_download=True,)if args.cpu_only:device_map = "cpu"else:device_map = "cuda"model = AutoModelForCausalLM.from_pretrained(args.checkpoint_path,device_map=device_map,trust_remote_code=True,resume_download=True,).eval()model.generation_config = GenerationConfig.from_pretrained(args.checkpoint_path, trust_remote_code=True, resume_download=True,)return model, tokenizerdef _parse_text(text):lines = text.split("\n")lines = [line for line in lines if line != ""]count = 0for i, line in enumerate(lines):if "```" in line:count += 1items = line.split("`")if count % 2 == 1:lines[i] = f'<pre><code class="language-{items[-1]}">'else:lines[i] = f"<br></code></pre>"else:if i > 0:if count % 2 == 1:line = line.replace("`", r"\`")line = line.replace("<", "&lt;")line = line.replace(">", "&gt;")line = line.replace(" ", "&nbsp;")line = line.replace("*", "&ast;")line = line.replace("_", "&lowbar;")line = line.replace("-", "&#45;")line = line.replace(".", "&#46;")line = line.replace("!", "&#33;")line = line.replace("(", "&#40;")line = line.replace(")", "&#41;")line = line.replace("$", "&#36;")lines[i] = "<br>" + linetext = "".join(lines)return textdef _launch_demo(args, model, tokenizer):uploaded_file_dir = os.environ.get("GRADIO_TEMP_DIR") or str(Path(tempfile.gettempdir()) / "gradio")def predict(_chatbot, task_history):query = task_history[-1][0]print("User: " + _parse_text(query))history_cp = copy.deepcopy(task_history)full_response = ""history_filter = []audio_idx = 1pre = ""global last_audiofor i, (q, a) in enumerate(history_cp):if isinstance(q, (tuple, list)):last_audio = q[0]q = f'Audio {audio_idx}: <audio>{q[0]}</audio>'pre += q + '\n'audio_idx += 1else:pre += qhistory_filter.append((pre, a))pre = ""history, message = history_filter[:-1], history_filter[-1][0]response, history = model.chat(tokenizer, message, history=history)ts_pattern = r"<\|\d{1,2}\.\d+\|>"all_time_stamps = re.findall(ts_pattern, response)print(response)if (len(all_time_stamps) > 0) and (len(all_time_stamps) % 2 ==0) and last_audio:ts_float = [ float(t.replace("<|","").replace("|>","")) for t in all_time_stamps]ts_float_pair = [ts_float[i:i + 2] for i in range(0,len(all_time_stamps),2)]# 读取音频文件format = os.path.splitext(last_audio)[-1].replace(".","")audio_file = AudioSegment.from_file(last_audio, format=format)chat_response_t = response.replace("<|", "").replace("|>", "")chat_response = chat_response_ttemp_dir = secrets.token_hex(20)temp_dir = Path(uploaded_file_dir) / temp_dirtemp_dir.mkdir(exist_ok=True, parents=True)# 截取音频文件for pair in ts_float_pair:audio_clip = audio_file[pair[0] * 1000: pair[1] * 1000]# 保存音频文件name = f"tmp{secrets.token_hex(5)}.{format}"filename = temp_dir / nameaudio_clip.export(filename, format=format)_chatbot[-1] = (_parse_text(query), chat_response)_chatbot.append((None, (str(filename),)))else:_chatbot[-1] = (_parse_text(query), response)full_response = _parse_text(response)task_history[-1] = (query, full_response)print("Qwen-Audio-Chat: " + _parse_text(full_response))return _chatbotdef regenerate(_chatbot, task_history):if not task_history:return _chatbotitem = task_history[-1]if item[1] is None:return _chatbottask_history[-1] = (item[0], None)chatbot_item = _chatbot.pop(-1)if chatbot_item[0] is None:_chatbot[-1] = (_chatbot[-1][0], None)else:_chatbot.append((chatbot_item[0], None))return predict(_chatbot, task_history)def add_text(history, task_history, text):history = history + [(_parse_text(text), None)]task_history = task_history + [(text, None)]return history, task_history, ""def add_file(history, task_history, file):history = history + [((file.name,), None)]task_history = task_history + [((file.name,), None)]return history, task_historydef add_mic(history, task_history, file):if file is None:return history, task_historyos.rename(file, file + '.wav')print("add_mic file:", file)print("add_mic history:", history)print("add_mic task_history:", task_history)# history = history + [((file.name,), None)]# task_history = task_history + [((file.name,), None)]task_history = task_history + [((file + '.wav',), None)]history = history + [((file + '.wav',), None)]print("task_history", task_history)return history, task_historydef reset_user_input():return gr.update(value="")def reset_state(task_history):task_history.clear()return []with gr.Blocks() as demo:gr.Markdown("""\
<p align="center"><img src="https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-Audio/logo.jpg" style="height: 80px"/><p>""")  ## todogr.Markdown("""<center><font size=8>Qwen-Audio-Chat Bot</center>""")gr.Markdown("""\
<center><font size=3>This WebUI is based on Qwen-Audio-Chat, developed by Alibaba Cloud. \
(本WebUI基于Qwen-Audio-Chat打造,实现聊天机器人功能。)</center>""")gr.Markdown("""\
<center><font size=4>Qwen-Audio <a href="https://modelscope.cn/models/qwen/Qwen-Audio/summary">🤖 </a> 
| <a href="https://huggingface.co/Qwen/Qwen-Audio">🤗</a>&nbsp | 
Qwen-Audio-Chat <a href="https://modelscope.cn/models/qwen/Qwen-Audio-Chat/summary">🤖 </a> | 
<a href="https://huggingface.co/Qwen/Qwen-Audio-Chat">🤗</a>&nbsp | 
&nbsp<a href="https://github.com/QwenLM/Qwen-Audio">Github</a></center>""")chatbot = gr.Chatbot(label='Qwen-Audio-Chat', elem_classes="control-height", height=750)query = gr.Textbox(lines=2, label='Input')task_history = gr.State([])mic = gr.Audio(source="microphone", type="filepath")with gr.Row():empty_bin = gr.Button("🧹 Clear History (清除历史)")submit_btn = gr.Button("🚀 Submit (发送)")regen_btn = gr.Button("🤔️ Regenerate (重试)")addfile_btn = gr.UploadButton("📁 Upload (上传文件)", file_types=["audio"])mic.change(add_mic, [chatbot, task_history, mic], [chatbot, task_history])submit_btn.click(add_text, [chatbot, task_history, query], [chatbot, task_history]).then(predict, [chatbot, task_history], [chatbot], show_progress=True)submit_btn.click(reset_user_input, [], [query])empty_bin.click(reset_state, [task_history], [chatbot], show_progress=True)regen_btn.click(regenerate, [chatbot, task_history], [chatbot], show_progress=True)addfile_btn.upload(add_file, [chatbot, task_history, addfile_btn], [chatbot, task_history], show_progress=True)gr.Markdown("""\
<font size=2>Note: This demo is governed by the original license of Qwen-Audio. \
We strongly advise users not to knowingly generate or allow others to knowingly generate harmful content, \
including hate speech, violence, pornography, deception, etc. \
(注:本演示受Qwen-Audio的许可协议限制。我们强烈建议,用户不应传播及不应允许他人传播以下内容,\
包括但不限于仇恨言论、暴力、色情、欺诈相关的有害信息。)""")demo.queue().launch(share=args.share,inbrowser=args.inbrowser,server_port=args.server_port,server_name=args.server_name,file_directories=["/tmp/"])def main():args = _get_args()model, tokenizer = _load_model_tokenizer(args)_launch_demo(args, model, tokenizer)if __name__ == '__main__':main()

五、对话聊天机器人运行实践

1、修改默认端口

注意下面代码中默认端口的设置,修改为6006
在这里插入图片描述

2、启动运行web chat机器人

执行以下命令启动对话聊天机器人

python /root/autodl-tmp/web_demo_audio.py

启动成功如下:
在这里插入图片描述

3、端口代理映射

使用autoDL SSH隧道工具代理端口
在这里插入图片描述

4、访问web聊天对话界面

在浏览器中打开链接 http://localhost:6006/ ,即可看到聊天界面。
在这里插入图片描述

5、普通对话聊天

在这里插入图片描述

6、音频文件识别

1)通过“上传文件”按钮,上传前面准备的音频文件
https://github.com/QwenLM/Qwen-Audio/raw/main/assets/audio/1272-128104-0000.flac
在这里插入图片描述

2)基于音频文件进行对话聊天
基于音频文件,测试模型对音频文件内容的识别是否准确
在这里插入图片描述

结语

本文的探索之旅即将结束,但我们对 Qwen-Audio-Chat 模型的深入理解和应用实践才刚刚开始。通过本文的指导,我们不仅成功部署了基于此模型的对话机器人,更对智能对话系统的构建有了更深刻的认识。

随着技术的不断演进,我们期待对话机器人在更多场景下展现出其独特的价值,为人类社会带来便利和创新。同时,我们也鼓励读者继续探索和实践,以推动智能对话技术的发展,实现更自然、更智能的交互体验。

在这里插入图片描述
🎯🔖更多专栏系列文章:AI大模型提示工程完全指南AI大模型探索之路(零基础入门)AI大模型预训练微调进阶AI大模型开源精选实践AI大模型RAG应用探索实践🔥🔥🔥 其他专栏可以查看博客主页📑

😎 作者介绍:我是寻道AI小兵,资深程序老猿,从业10年+、互联网系统架构师,目前专注于AIGC的探索。
📖 技术交流:欢迎关注【小兵的AI视界】公众号或扫描下方👇二维码,加入技术交流群,开启编程探索之旅。
💘精心准备📚500本编程经典书籍、💎AI专业教程,以及高效AI工具。等你加入,与我们一同成长,共铸辉煌未来。
如果文章内容对您有所触动,别忘了点赞、⭐关注,收藏!加入我,让我们携手同行AI的探索之旅,一起开启智能时代的大门!

相关文章:

【Qwen-Audio部署实战】Qwen-Audio-Chat模型之对话机器人部署测试

系列篇章&#x1f4a5; No.文章1【Qwen部署实战】探索Qwen-7B-Chat&#xff1a;阿里云大型语言模型的对话实践2【Qwen2部署实战】Qwen2初体验&#xff1a;用Transformers打造智能聊天机器人3【Qwen2部署实战】探索Qwen2-7B&#xff1a;通过FastApi框架实现API的部署与调用4【Q…...

第一百八十五节 Java XML教程 - Java DOM简介

Java XML教程 - Java DOM简介 DOM是标准的树结构&#xff0c;其中每个节点包含来自XML结构的一个组件。 XML文档中两种最常见的节点类型是元素节点和文本节点。 使用Java DOM API&#xff0c;我们可以创建节点&#xff0c;删除节点&#xff0c;更改其内容&#xff0c;并遍历节…...

一款功能强大且免费的图片查看和管理工具

XnView MP是一款功能强大且免费的图片查看和管理工具&#xff0c;支持多种平台&#xff08;Windows、Mac和Linux&#xff09;&#xff0c;并基于相同的源代码实现统一的用户界面和体验。它不仅能够查看各种图片格式&#xff0c;还提供了丰富的编辑和管理功能。 图片查看与浏览…...

动手学强化学习 第 11 章 TRPO 算法(TRPOContinuous) 训练代码

基于 Hands-on-RL/第11章-TRPO算法.ipynb at main boyu-ai/Hands-on-RL GitHub 理论 TRPO 算法 修改了警告和报错 运行环境 Debian GNU/Linux 12 Python 3.9.19 torch 2.0.1 gym 0.26.2 运行代码 TRPOContinuous.py #!/usr/bin/env pythonimport torch import numpy a…...

数量关系模块

三年后指的不是现在 选A注意单位 注意单位换算 A 正方形减去扇形 256-X5y 那么小李拿的一定是末尾是1或者是6&#xff0c;所以小李拿的是26&#xff0c;那么y46&#xff0c;那么小王或者小周拿的是92&#xff0c;所以选择三个数之和等于92的&#xff0c;所以选择D 分数 百分数 …...

滑模面、趋近律设计过程详解(滑模控制)

目录 1. 确定系统的状态变量和目标2. 定义滑模面3. 选择滑模面的参数4. 设计控制律5. 验证滑模面设计6. 总结 设计滑模面&#xff08;Sliding Surface&#xff09;是滑模控制&#xff08;Sliding Mode Control&#xff0c;SMC&#xff09;中的关键步骤。滑模控制是一种鲁棒控制…...

SQL Server 端口配置

目录 默认端口 更改端口 示例&#xff1a;更改 TCP 端口 示例&#xff1a;验证端口设置 远程连接测试 示例&#xff1a;使用 telnet 测试连接 配置防火墙 示例&#xff1a;Windows 防火墙设置 远程连接测试 示例&#xff1a;使用 telnet 测试连接 默认端口 TCP/IP: …...

同一窗口还是新窗口打开链接更利于SEO优化

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storm…...

kafka 安装

docker安装kafka(KRaft 模式) KRaft模式不再对Zookeeper依赖。 docker run -d --name kafka-kraft \-p 9092:9092 -p 9093:9093 \-e KAFKA_PROCESS_ROLESbroker,controller \-e KAFKA_NODE_ID1 \-e KAFKA_CONTROLLER_QUORUM_VOTERS1127.0.0.1:9093 \-e KAFKA_LISTENERSPLAINTEX…...

消息队列中间件 - Kafka:高效数据流处理的引擎

作者&#xff1a;逍遥Sean 简介&#xff1a;一个主修Java的Web网站\游戏服务器后端开发者 主页&#xff1a;https://blog.csdn.net/Ureliable 觉得博主文章不错的话&#xff0c;可以三连支持一下~ 如有疑问和建议&#xff0c;请私信或评论留言&#xff01; 前言 在现代大数据和…...

el-table表格动态合并相同数据单元格(可指定列+自定义合并)

el-table表格动态合并相同数据单元格(可指定列自定义合并)_el-table 合并单元格动态-CSDN博客 vue2elementUI表格实现实现多列动态合并_element table动态合并列-CSDN博客...

复习Nginx

1.关于Nginx Nginx的关键特性 1.支持高并发 2.内存资源消耗低 3.高扩展性&#xff08;模块化设计&#xff09; 4.高可用性&#xff08;master-worker&#xff09; Nginx运行架构 注意 默认情况下&#xff0c;Nginx会创建和服务器cpu核心数量相等的worker进程 worker进程之间…...

nvm:Node.js 版本管理工具

nvm&#xff08;Node Version Manager&#xff09;是一个用于管理多个 Node.js 版本的工具&#xff0c;它允许你在同一个系统上安装和使用不同版本的 Node.js。这对于开发者来说非常有用&#xff0c;特别是当不同的项目需要不同版本的 Node.js 时。 以下是 nvm 的一些主要特性…...

springboot校园商店配送系统-计算机毕业设计源码68448

摘要 本文详细阐述了基于Spring Boot框架的校园商店配送系统的设计与实现过程。该系统针对校园内的用户需求&#xff0c;整合了用户注册与登录、商品浏览与购买、订单管理、配送追踪、用户反馈收集以及后台管理等功能&#xff0c;为校园内的普通用户、商家、配送员和管理员提供…...

【Redis 初阶】客户端(C++ 使用样例列表)

一、编写 helloworld 需要先使用 redis-plus-plus 连接一下 Redis 服务器&#xff0c;再使用 ping 命令检测连通性。 1、Makefile Redis 库最多可以支持到 C17 版本。&#xff08;如果是用 Centos&#xff0c;需要注意 gcc/g 的版本&#xff0c;看是否支持 C17。不支持的话&a…...

【STM32】STM32单片机入门

个人主页~ 这是一个新的系列&#xff0c;stm32单片机系列&#xff0c;资料都是从网上找的&#xff0c;主要参考江协科技还有正点原子以及csdn博客等资料&#xff0c;以一个一点没有接触过单片机但有一点编程基础的小白视角开始stm32单片机的学习&#xff0c;希望能对也没有学过…...

学生信息管理系统(Python+PySimpleGUI+MySQL)

吐槽一下 经过一段时间学习pymysql的经历&#xff0c;我深刻的体会到了pymysql的不靠谱之处&#xff1b; 就是在使用int型传参&#xff0c;我写的sql语句中格式化%d了之后&#xff0c;我在要传入的数据传递的每一步的去强制转换了&#xff0c;但是他还是会报错&#xff0c;说我…...

Java8.0标准之重要特性及用法实例(十九)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 新书发布&#xff1a;《Android系统多媒体进阶实战》&#x1f680; 优质专栏&#xff1a; Audio工程师进阶系列…...

Linux系统中,`buffer`和`cache` 区别

在Linux系统中&#xff0c;buffer和cache都是操作系统用来提高磁盘I/O性能的机制&#xff0c;它们通过将数据暂存于内存中来减少对磁盘的直接访问。尽管它们的目的相似&#xff0c;但它们在实现和用途上有所不同。 Buffer 定义&#xff1a;buffer主要用于存储即将被写入磁盘的…...

python创建进度条的两个手搓方法

# 使用\b 回删进行手搓 import sys,time for i in range(1, 101):# 这里的10代表你的进度: 一个汉字2字节print(你的进度:,str(i)\b*(i10),flushTrue,end)time.sleep(0.5) # 利用\r手搓 import sys,time for i in range(1, 101):# \r光标回到开头print("\r", end&qu…...

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

DBAPI如何优雅的获取单条数据

API如何优雅的获取单条数据 案例一 对于查询类API&#xff0c;查询的是单条数据&#xff0c;比如根据主键ID查询用户信息&#xff0c;sql如下&#xff1a; select id, name, age from user where id #{id}API默认返回的数据格式是多条的&#xff0c;如下&#xff1a; {&qu…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...

华为OD机试-最短木板长度-二分法(A卷,100分)

此题是一个最大化最小值的典型例题&#xff0c; 因为搜索范围是有界的&#xff0c;上界最大木板长度补充的全部木料长度&#xff0c;下界最小木板长度&#xff1b; 即left0,right10^6; 我们可以设置一个候选值x(mid)&#xff0c;将木板的长度全部都补充到x&#xff0c;如果成功…...