Qwen2-VL-2B-Instruct在Qt桌面应用中的集成:开发跨平台图像分析工具

news2026/3/30 12:20:11
Qwen2-VL-2B-Instruct在Qt桌面应用中的集成开发跨平台图像分析工具1. 引言如果你是做桌面应用开发的特别是用C和Qt的最近可能也注意到了AI模型带来的新机会。很多开发者都在想怎么把这些强大的AI能力比如看图说话、图像理解直接做到自己的软件里让用户不用打开网页在本地应用里就能用上。今天要聊的就是怎么把Qwen2-VL-2B-Instruct这个能看懂图片的模型集成到一个用Qt写的桌面程序里。这个模型不大但理解图片内容的能力挺不错很适合在本地环境跑。我们的目标很简单做一个带图形界面的小工具用户把图片拖进去它就能告诉你图片里有什么还能把历史记录存下来。最关键的是这个工具能在Windows、Linux、macOS上都能编译运行一次开发到处使用。用Qt来做这件事有几个好处。首先Qt的跨平台特性是经过时间考验的界面写一套代码到哪个系统上都能用。其次Qt本身对网络、文件、界面交互的支持很全面我们不用再去找一堆第三方库来拼凑。最后对于C开发者来说在熟悉的开发环境里接入AI能力学习成本相对较低。接下来我就带你一步步走通这个流程从环境准备到最终打包看看怎么把一个AI模型的能力变成用户桌面上一个实实在在的、点击即用的工具。2. 为什么选择Qt和C来集成视觉语言模型在做技术选型的时候我们总会问为什么是它把Qwen2-VL-2B-Instruct这样的模型集成到桌面端选择Qt和C这套组合背后有挺实际的考虑。先说Qt。它的核心优势就是“一次编写随处编译”。我们写界面最怕的就是给Windows做一套给macOS又得重写一套Linux还得再来一次。Qt把底层系统那些差异都封装好了我们用QWidget或者QML写出来的界面在三个主流桌面系统上都能原生地跑起来看起来和用起来都像是那个系统原生的应用。这对于我们想快速做出一个能在多平台分发的工具来说省了太多事。然后是C。虽然现在Python在AI领域很火但当我们最终要交付一个给终端用户使用的、需要安装的桌面软件时C的优势就出来了。用C写的Qt应用可以编译成真正的本地可执行文件不需要用户电脑上预先安装Python解释器或者一大堆依赖包。最终用户拿到手的可能就是一个几十兆的安装包双击安装就能用体验上更接近他们平时用的那些专业软件。这对于提升产品的专业感和易用性很有帮助。再来看我们要集成的模型Qwen2-VL-2B-Instruct。它是一个“视觉语言”模型简单说就是既能看懂图片视觉又能用文字回答问题或描述内容语言。2B指的是它的参数规模属于比较轻量级的这意味着它对硬件的要求不会太高在普通开发机甚至一些配置不错的个人电脑上都有可能跑起来或者通过API调用。我们做桌面集成模型的大小和推理速度是需要重点考虑的太庞大的模型本地部署会非常困难。最后从开发效率上看Qt提供了丰富的类库。比如我们要做图片拖拽功能用Qt的Drag and Drop机制几行代码就能实现。要显示图片和文本用QLabel和QTextEdit也很方便。要管理历史记录Qt的SQL模块或者简单的文件读写都能胜任。这些现成的“轮子”让我们能把精力集中在核心的AI功能集成上而不是从头去造每一个基础部件。所以总结起来用Qt和C来干这件事图的就是它的跨平台能力能让软件覆盖更多用户它的本地编译特性能让软件用起来更简单而它丰富的框架支持又能让我们开发起来更顺手。3. 开发环境与项目初始化工欲善其事必先利其器。在开始写代码之前我们得先把“厨房”收拾好。这里我会假设你已经有了一些C和Qt的基础电脑上大概也装好了编译环境。如果没有跟着步骤走一遍也不复杂。3.1 基础环境准备首先你需要一个C编译器。在Windows上可以用Visual Studio自带的MSVC或者安装MinGW。在Linux上g或clang通常系统自带。在macOS上安装Xcode Command Line Tools就能获得clang。接下来是Qt。我强烈建议使用Qt的在线安装器Qt Maintenance Tool来安装。这样你可以自由选择需要的版本和组件。对于我们这个项目安装Qt 6.x的某个长期支持版本比如6.5或6.6是比较稳妥的选择。在安装时记得勾选对应你编译器的那套套件比如“MSVC 2019 64-bit”或者“MinGW 64-bit”。另外把“Qt Creator”这个集成开发环境也装上它会让你后续的开发调试方便很多。项目管理和构建工具我们选用CMake。这是现在Qt官方也主推的构建系统比传统的qmake更强大和通用。确保你的CMake版本在3.16以上。在Windows上你可以从CMake官网下载安装包在Linux和macOS上用包管理器如apt、brew安装也很方便。3.2 创建Qt CMake项目打开Qt Creator选择“New Project”。在项目类型里选择“Application (Qt)”下的“Qt Widgets Application”因为我们做一个传统的带窗口的桌面应用。给项目起个名字比如ImageAnalyzer。关键的一步是在“Choose Build System”那里务必选择“CMake”而不是“qmake”。然后一路下一步Qt Creator会为你生成一个最基础的带窗口的CMake项目。生成的项目结构大概长这样ImageAnalyzer/ ├── CMakeLists.txt ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h ├── mainwindow.ui └── ... (其他可能文件)这个CMakeLists.txt文件就是项目的总蓝图。Qt Creator已经帮我们写好了基础的配置包括找到Qt的库、链接必要的模块。我们可以先编译运行一下这个空白项目确保基础环境没问题。点击Qt Creator左下角的绿色三角运行按钮你应该能看到一个空白的窗口弹出来。3.3 引入必要的Qt模块我们的工具需要一些特定功能因此要在CMakeLists.txt里告诉CMake我们需要额外的Qt模块。用文本编辑器打开CMakeLists.txt找到类似下面这行find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets)这行代码是说我们的项目需要Qt6的Core、Gui和Widgets这几个核心模块。为了支持网络请求调用模型API、显示图片、使用对话框等我们需要再添加几个。把这行修改成find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets Network Multimedia PrintSupport)这里新增了Network用于发起HTTP请求和我们的模型服务通信。Multimedia可能用于更高级的图片预览或处理基础显示用Widgets也够但加上更灵活。PrintSupport虽然不是必须但有时用户可能想打印分析结果先加上以备不时之需。修改完后记得在Qt Creator里执行一下“Build - Run CMake”或者直接重新构建项目让CMake重新配置一下。环境搭好了项目架子也立起来了接下来我们就可以开始设计这个图像分析工具长什么样以及它该怎么工作了。4. 设计应用界面与核心功能在动手写代码之前先想清楚这个工具要做什么以及用户怎么和它交互。一个好的设计能让我们后续的开发更有条理避免来回折腾。4.1 功能需求梳理我们的“图像分析工具”核心功能其实很聚焦图片输入用户能方便地把图片交给程序。方式可以多样从菜单打开文件、把图片文件直接拖拽到窗口里或者从剪贴板粘贴。图片显示程序得把用户选中的图片展示出来让用户确认是不是他要分析的那一张。触发分析用户点击一个按钮比如“开始分析”程序就把图片发送给Qwen2-VL模型并获取模型的文字描述。结果展示把模型返回的、关于图片内容的文字描述清晰友好地显示给用户。历史管理用户分析过的图片和结果最好能保存下来方便以后查看。这可以是一个列表点击某条历史记录能重新显示当时的图片和结果。4.2 使用Qt Designer布局界面Qt Creator内置了一个叫Qt Designer的可视化界面设计工具我们用它来“画”出窗口。双击项目里的mainwindow.ui文件就会打开它。我建议的界面布局可以分成几个主要区域顶部菜单栏和工具栏放一些通用操作如“打开文件”、“退出”。左侧图片预览区用一个比较大的QLabel来显示图片。把这个QLabel的scaledContents属性设为true这样图片会自动缩放来适应标签大小。同时为了支持拖拽需要设置它的acceptDrops属性为true。右侧控制与结果区这部分垂直布局。上方放一个QPushButton文字设为“分析图片”用来触发分析动作。中间放一个QTextEdit用来显示模型返回的文字描述。可以设置它为只读readOnly因为用户通常不需要编辑这个结果。下方放一个QListWidget用来作为历史记录列表。每一行可以简单显示图片文件名和部分分析结果。你可以通过拖拽控件并使用布局管理器如水平布局Horizontal Layout、垂直布局Vertical Layout、网格布局Grid Layout来排列它们让界面在不同窗口大小时也能自适应。设计完大致如下图示意想象一下----------------------------------------- | [菜单] 打开 | 帮助 | ---------------------------------------- | | [分析图片] 按钮 | | | | | 图片预览区 ------------------------ | (QLabel) | | | | 分析结果展示区 | | | (QTextEdit) | | ------------------------ | | | | | 历史记录列表 | | | (QListWidget) | ----------------------------------------给这些重要的控件起一个容易记的“对象名称”比如把显示图片的QLabel命名为imageLabel把分析按钮命名为analyzeButton把结果显示框命名为resultTextEdit把历史列表命名为historyListWidget。这样我们在代码里就能方便地找到并操作它们了。界面设计好了它就相当于一个静态的“壳子”。接下来我们要编写代码让这个壳子里的按钮能点击、能响应拖拽、能发送网络请求也就是让它真正“活”起来。5. 实现图片加载与模型调用逻辑现在进入核心的代码部分。我们要让界面上的按钮和拖拽区域起作用并且能和后端的AI模型服务“对话”。5.1 启用拖拽与图片加载首先让我们的图片预览区支持拖拽。在MainWindow类的头文件(mainwindow.h)里我们需要重写两个拖拽相关的事件处理函数。在类声明中添加protected: void dragEnterEvent(QDragEnterEvent *event) override; void dropEvent(QDropEvent *event) override;然后在mainwindow.cpp中实现它们void MainWindow::dragEnterEvent(QDragEnterEvent *event) { // 当用户拖拽东西进入窗口时判断是不是我们想要的比如图片文件 if (event-mimeData()-hasUrls()) { // 简单检查如果拖入的是文件就先接受这个动作 event-acceptProposedAction(); } } void MainWindow::dropEvent(QDropEvent *event) { // 当用户在窗口内松开鼠标完成拖拽时处理拖入的内容 const QMimeData *mimeData event-mimeData(); if (mimeData-hasUrls()) { QListQUrl urlList mimeData-urls(); if (!urlList.isEmpty()) { // 取第一个拖入的文件路径本地文件路径 QString filePath urlList.first().toLocalFile(); // 检查文件后缀简单判断是否为图片 if (filePath.endsWith(.png, Qt::CaseInsensitive) || filePath.endsWith(.jpg, Qt::CaseInsensitive) || filePath.endsWith(.jpeg, Qt::CaseInsensitive)) { loadImage(filePath); // 调用加载图片的函数 } else { QMessageBox::warning(this, 文件类型错误, 请拖入图片文件PNG/JPG格式。); } } } }同时我们需要实现loadImage函数它的作用是把图片文件加载并显示在imageLabel上同时把文件路径保存下来以备后续发送给模型。void MainWindow::loadImage(const QString filePath) { QPixmap pixmap(filePath); if (pixmap.isNull()) { QMessageBox::warning(this, 加载失败, 无法加载图片文件请检查文件是否损坏。); return; } // 缩放图片以适应Label同时保持宽高比 ui-imageLabel-setPixmap(pixmap.scaled(ui-imageLabel-size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); currentImagePath filePath; // 保存当前图片路径假设currentImagePath是类的成员变量 ui-resultTextEdit-clear(); // 加载新图片时清空旧的结果 }别忘了在MainWindow类中声明currentImagePath这个私有成员变量QString currentImagePath;以及loadImage这个私有槽函数或方法。5.2 构建HTTP客户端与模型通信模型服务通常通过HTTP API提供。假设Qwen2-VL-2B-Instruct模型已经在一个本地服务比如用ollama或vLLM部署或某个远程API上跑起来了它提供了一个接收图片并返回描述的接口。我们使用Qt的QNetworkAccessManager来发起HTTP请求。在MainWindow类中添加一个成员变量private: QNetworkAccessManager *networkManager;在MainWindow的构造函数中初始化它MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui-setupUi(this); // ... 其他初始化代码比如连接信号槽 networkManager new QNetworkAccessManager(this); // 连接网络请求完成的信号到我们的处理槽函数 connect(networkManager, QNetworkAccessManager::finished, this, MainWindow::onAnalysisFinished); }现在实现“分析图片”按钮的槽函数。当用户点击按钮时我们检查是否有图片被加载然后构建一个HTTP请求发送出去。void MainWindow::on_analyzeButton_clicked() { if (currentImagePath.isEmpty()) { QMessageBox::information(this, 提示, 请先选择或拖入一张图片。); return; } ui-analyzeButton-setEnabled(false); // 防止重复点击 ui-resultTextEdit-setPlainText(正在分析中请稍候...); // 1. 构建请求 QUrl serviceUrl(http://127.0.0.1:11434/api/generate); // 假设这是本地ollama服务的API地址 QNetworkRequest request(serviceUrl); request.setHeader(QNetworkRequest::ContentTypeHeader, application/json); // 2. 准备请求数据JSON格式 QJsonObject jsonBody; jsonBody[model] qwen2-vl:2b-instruct; // 指定模型 jsonBody[prompt] 描述这张图片的内容。; // 给模型的指令 jsonBody[stream] false; // 我们不需要流式响应 // 3. 将图片转换为Base64编码并放入JSON QFile imageFile(currentImagePath); if (!imageFile.open(QIODevice::ReadOnly)) { // 处理文件打开错误 return; } QByteArray imageData imageFile.readAll(); QString base64Image QString::fromLatin1(imageData.toBase64()); // 注意实际API可能要求图片数据放在特定的字段结构中这里仅为示例 // 例如有些API要求 {model: ..., prompt: ..., images: [data:image/jpeg;base64,...]} // 请根据你使用的模型服务的实际API文档调整。 jsonBody[images] QJsonArray{base64Image}; QJsonDocument doc(jsonBody); QByteArray postData doc.toJson(); // 4. 发送POST请求 networkManager-post(request, postData); }这段代码的关键是构建符合模型服务API要求的JSON数据。你需要根据你实际使用的模型服务如ollama, OpenAIVision API或自行部署的后端的API文档来调整jsonBody的结构和字段名。上面的代码只是一个示例框架。5.3 处理模型响应与更新界面请求发出去后我们通过之前连接的finished信号来处理响应。实现onAnalysisFinished槽函数void MainWindow::onAnalysisFinished(QNetworkReply *reply) { ui-analyzeButton-setEnabled(true); // 恢复按钮 if (reply-error() ! QNetworkReply::NoError) { ui-resultTextEdit-setPlainText(请求失败: reply-errorString()); reply-deleteLater(); return; } QByteArray responseData reply-readAll(); reply-deleteLater(); // 重要及时清理reply对象 // 解析JSON响应 QJsonDocument jsonDoc QJsonDocument::fromJson(responseData); if (jsonDoc.isNull()) { ui-resultTextEdit-setPlainText(解析响应失败。); return; } QJsonObject jsonObj jsonDoc.object(); // 从响应JSON中提取模型生成的文本。字段名需根据实际API调整。 // 例如ollama的响应里可能有一个response字段。 QString resultText jsonObj.value(response).toString(); if (resultText.isEmpty()) { resultText 模型未返回有效描述。; } // 更新界面显示结果 ui-resultTextEdit-setPlainText(resultText); // 将本次分析添加到历史记录 addToHistory(currentImagePath, resultText); }最后我们实现addToHistory函数把本次分析的结果保存下来并更新历史列表。void MainWindow::addToHistory(const QString imagePath, const QString result) { QFileInfo fileInfo(imagePath); QString displayText QString(%1: %2).arg(fileInfo.fileName()).arg(result.left(50) ...); // 只显示前50个字符 ui-historyListWidget-addItem(displayText); // 这里可以更复杂比如把完整信息图片路径、结果、时间戳保存到文件或数据库 // 简单示例保存到内存中的列表 HistoryItem item; item.imagePath imagePath; item.result result; item.timestamp QDateTime::currentDateTime(); historyItems.append(item); // historyItems 是 QVectorHistoryItem 类型的成员变量 }这样一个基本的图片分析流程就打通了拖入图片 - 点击分析 - 发送请求 - 解析结果 - 显示并保存。当然这里还有很多可以完善的地方比如错误处理更细致、支持更多图片格式、显示网络请求进度、让历史记录可点击查看详情等等。6. 实现历史记录与数据持久化一个工具如果只能分析一次分析完就丢那实用性就大打折扣。历史记录功能能让用户回顾之前的工作是提升体验的关键。我们可以从简单到复杂来实现它。6.1 设计历史记录数据结构首先定义一个结构体来保存单条历史记录的所有信息。在mainwindow.h中或者单独的头文件添加struct HistoryItem { QString imagePath; // 图片的本地路径 QString result; // 模型返回的完整描述文本 QDateTime timestamp; // 分析的时间点 };然后在MainWindow类里添加一个容器来存储这些记录private: QVectorHistoryItem historyItems;QVector在这里是个不错的选择它提供了快速的随机访问适合我们按顺序展示历史列表。6.2 增强历史列表的交互现在我们的历史列表QListWidget只显示了文件名和结果片段。我们希望点击某一条记录时能重新加载对应的图片和完整结果。在Qt Designer里或者在代码里将历史列表historyListWidget的itemClicked信号连接到一个新的槽函数上。在MainWindow构造函数中添加connect(ui-historyListWidget, QListWidget::itemClicked, this, MainWindow::onHistoryItemClicked);然后实现这个槽函数void MainWindow::onHistoryItemClicked(QListWidgetItem *item) { int row ui-historyListWidget-row(item); if (row 0 || row historyItems.size()) { return; } const HistoryItem history historyItems.at(row); // 重新加载图片 loadImage(history.imagePath); // 显示完整的历史结果 ui-resultTextEdit-setPlainText(history.result); }这样用户点击历史列表中的任何一项主界面就会立刻切换到那次分析的状态。6.3 实现数据持久化保存到文件内存中的记录在程序退出后就消失了。为了让历史记录能永久保存我们需要把它们写到磁盘上。一个简单的方法是使用JSON格式。我们可以在程序关闭时MainWindow的析构函数或closeEvent中保存在程序启动时加载。这里以closeEvent为例void MainWindow::closeEvent(QCloseEvent *event) { saveHistoryToFile(); event-accept(); // 接受关闭事件 } void MainWindow::saveHistoryToFile() { QJsonArray historyArray; for (const auto item : historyItems) { QJsonObject obj; obj[imagePath] item.imagePath; obj[result] item.result; obj[timestamp] item.timestamp.toString(Qt::ISODate); // 用ISO标准格式保存时间 historyArray.append(obj); } QJsonDocument doc(historyArray); QFile file(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) /history.json); // QStandardPaths帮我们找到适合存放应用数据的目录 if (file.open(QIODevice::WriteOnly)) { file.write(doc.toJson()); file.close(); } }对应的在MainWindow的构造函数末尾添加加载历史的代码void MainWindow::loadHistoryFromFile() { QString filePath QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) /history.json; QFile file(filePath); if (!file.open(QIODevice::ReadOnly)) { return; // 文件不存在或打不开说明是第一次运行 } QByteArray data file.readAll(); file.close(); QJsonDocument doc QJsonDocument::fromJson(data); if (!doc.isArray()) return; QJsonArray array doc.array(); historyItems.clear(); for (const auto value : array) { QJsonObject obj value.toObject(); HistoryItem item; item.imagePath obj[imagePath].toString(); item.result obj[result].toString(); item.timestamp QDateTime::fromString(obj[timestamp].toString(), Qt::ISODate); historyItems.append(item); // 同时更新列表控件的显示简单显示 QFileInfo fi(item.imagePath); ui-historyListWidget-addItem(QString(%1: %2).arg(fi.fileName()).arg(item.result.left(50)...)); } }记得在构造函数中调用loadHistoryFromFile()。这样一个具备基本持久化功能的历史记录就完成了。当然你还可以考虑更复杂的方案比如使用SQLite数据库来存储这样可以更方便地查询、删除单条记录或者存储图片的缩略图等。7. 跨平台编译、打包与分发代码写完了功能也实现了最后一步是把它变成用户能在自己电脑上运行的软件。跨平台是Qt的强项但要让程序在三个系统上都能顺利编译和运行还是有一些细节要注意。7.1 跨平台编译注意事项我们的代码本身是平台无关的这要归功于Qt的封装。但在不同平台上编译时环境配置略有不同Windows在Qt Creator中确保你选择了正确的“Kit”比如“Desktop Qt 6.5.0 MSVC2019 64bit”。编译后会在构建目录通常是build-项目名-Desktop_Qt_...-Release下生成一个.exe文件。这个.exe不能直接双击运行因为它依赖一堆Qt的DLL文件。Linux过程类似选择对应的GCC套件进行编译。生成的可执行文件同样依赖系统的Qt库。macOS选择Clang套件编译会生成一个.app的应用程序包。7.2 使用windeployqtWindows或macdeployqtmacOS打包Qt提供了命令行工具来帮助我们收集所有依赖项制作成可以独立分发的软件包。在Windows上用MSVC或MinGW编译一个Release版本的程序。打开Qt 6.5.0 64-bit for Desktop这样的命令行终端在开始菜单的Qt文件夹里能找到。切换到你的.exe文件所在的目录。运行命令windeployqt --release --no-compiler-runtime --no-angle --no-opengl-sw YourAppName.exe这个命令会把所有需要的Qt库、插件等复制到当前目录。现在把这个目录压缩成一个ZIP文件用户解压后就能运行了。在macOS上编译Release版本。在终端中进入你的.app包所在的目录通常在build-项目名-Desktop_Qt_...-Release下的YourAppName.app。运行命令macdeployqt YourAppName.app这会创建一个自包含的应用程序包。你可以直接右键这个.app选择“显示包内容”来查看里面打包好的所有文件。在Linux上情况稍微复杂因为Linux发行版众多。一种常见做法是提供AppImage格式。你可以使用linuxdeployqt工具需要单独下载来打包。或者更简单的方式是提供源代码和清晰的编译指南让用户在自己的系统上编译因为他们通常可以通过包管理器轻松安装Qt开发库。7.3 编写简单的使用说明无论你分发的是压缩包还是安装程序附上一个简单的README.txt文件总是好的。里面可以写上软件名称和版本。简要的功能介绍。最重要的运行前提。明确告知用户运行本工具前必须确保Qwen2-VL-2B-Instruct模型服务已经在本地运行例如通过ollama run qwen2-vl:2b-instruct命令启动并且API地址代码中的http://127.0.0.1:11434需要与实际情况一致。如果用户没有启动模型服务工具将无法工作。对于Windows用户提醒他们解压到不含中文和空格的路径。你的联系方式如果需要。8. 总结走完这一趟你会发现把一个前沿的AI模型能力塞进一个传统的桌面应用里并没有想象中那么神秘。核心思路就是把模型服务当作一个黑盒API我们的Qt程序就是一个带有友好界面的HTTP客户端。整个过程的关键点在于几个环节的衔接Qt界面捕获用户操作拖拽、点击 - 程序逻辑处理加载图片、编码 - 通过网络请求与模型API通信 - 解析返回数据并更新界面。每一个环节Qt都提供了成熟稳定的组件来支持这让集成工作变得有章可循。当然我们做的这个工具还是一个“最小可行产品”。在实际项目中你可能还需要考虑更多比如更健壮的错误处理网络超时、服务未启动、图片过大等情况。用户体验优化在分析时显示一个等待动画支持批量图片分析允许用户自定义提示词而不仅仅是“描述这张图片”。功能扩展集成多个不同的视觉模型让用户选择或者加入图片的基本编辑功能裁剪、旋转后再分析。部署简化把模型服务也打包进来做成一个完全离线的单机应用但这会大大增加分发包的体积和复杂度。但无论如何这个项目已经为你打通了一条路。它证明了用C和Qt这样的经典技术栈完全可以拥抱和集成最新的AI能力做出实用、高效且跨平台的桌面工具。希望这个实践能给你带来一些启发也许你的下一个项目就可以从这里开始添加更多有趣的功能。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。

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

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

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

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

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

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

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

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

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…