RAG开源项目Qanything源码阅读1-概述+服务

原文:前沿重器[45] RAG开源项目Qanything源码阅读1-概述+服务
项目:https://github.com/netease-youdao/QAnything


1, 简介

相比于论文中的对RAG的探索,实践更讲求实用性和全链路的完整性,类似文档处理、精排等逻辑在现实中的使用,一个很快的学习方式就是看开源项目,随着RAG项目的逐渐成熟,完整的开源项目也逐渐变多,包括langchain在内,类似Qanything、RAGflow、fastRAG。

Qanything 开源RAG项目 完整程度:

  • RAG全流程都具备,从文件上传、处理到在线推理、排序等,关键模块都是有的,而且中文注释,注释和文档也比较完善,很适合学习。
  • 包括完整的前后端体系。
  • 部署支持多环境和多种功能,从他多个文档里可以看到,支持linux、windows、Mac等多个环境,而且也有很丰富的教程。

2, 项目内代码结构概述

因为整个项目要适配多平台,而且RAG本身是一个完整的系统,所以有大量算法外围的工作,如好几个中间件如milvus,es,mysql,同时有docker、windows等环境的配置教程,还是比较完善的,先来看一眼根目录中的内容。

|-- Dockerfile  # docker构造文件
|-- FAQ.md  # 常见问题回答
|-- FAQ_zh.md # 常见问题回答
|-- LICENSE  # 证书
|-- README.md # README文档
|-- README_zh.md# README中文文档
|-- assets  # 一些模型之类的文件会放在这里
|-- close.sh # 关闭脚本
|-- docker-compose-linux.yaml # docker构造所需要的yaml文件,linux专用
|-- docker-compose-windows.yaml # docker构造所需要的yaml文件,windows专用
|-- docs  # 各种使用文档
|-- etc   # 其他文件,此处有一个prompt
|-- qanything_kernel # qanything的核心带代码,基本是python,包括服务、算法等
|-- requirements.txt # python依赖
|-- run.sh  # 启动脚本
|-- scripts  # 其他脚本
|-- third_party # 三方库
`-- volumes  # 数据库容器的外部映射地址
  • 根目录下的内容主要集中在服务层面的内容,如docker、服务的启停(run/close)、各种文档(README、docs)等。
  • 各种三方的资源似乎都有,可以借此学习一下各种相关组件的知识。
  • 算法的核心代码应该是在qanything_kernel里面。

2.1,qanything_kernel中的文件

|-- __init__.py # 空的
|-- configs  # 这里是模型和服务的配置,还有prompt之类的
|-- connector # 中间件的连接工具
|-- core  # milvus、es、mysql的都在里面,大家其实都能参考着用的
|-- dependent_server # 独立服务,这里主要是放大模型服务、ocr服务(图片文字抽取)、重排模型服务的
|-- qanything_server # qanything的核心服务,也是对外的服务,另外还有一些js文件和图片素材,应该是给前端用的。
`-- utils    # 零散的代码工具。这里可以说是宝藏了,里面挺多工具函数自己平时都能用的,类似safe_get等,另外很多文件处理的工具,类似文件加载、切片等,都在里面。

这一层就基本到服务内部了,挺多核心的东西都在这里的。

3,服务结构

通过这个也可以看出完整的RAG系统可能包含什么部分,这个从服务启动的脚本里面能逐步找到的。

首先是服务启动,找到./scripts/run_for_local_option.sh这个东西,因为本身是python服务,所以启动的时候大都避不开命令python,排除掉一些在线请求的服务,只考虑local模式,并过滤一些大概可以找到这几个命令:

compute_capability=$(python3 scripts/get_cuda_capability.py $gpu_id1)
nohup python3 -u llm_server_entrypoint.py --host="0.0.0.0" --port=36001 --model-path="tokenizer_assets" --model-url="0.0.0.0:10001" > /workspace/qanything_local/logs/debug_logs/llm_server_entrypoint.log 2>&1 &
nohup python3 -u qanything_kernel/dependent_server/rerank_for_local_serve/rerank_server.py > /workspace/qanything_local/logs/debug_logs/rerank_server.log 2>&1 &
CUDA_VISIBLE_DEVICES=$gpu_id2 nohup python3 -u qanything_kernel/dependent_server/ocr_serve/ocr_server.py > /workspace/qanything_local/logs/debug_logs/ocr_server.log 2>&1 &
nohup python3 -u qanything_kernel/qanything_server/sanic_api.py --mode "local" > /workspace/qanything_local/logs/debug_logs/sanic_api.log 2>&1 &
  • scripts/get_cuda_capability.py:检测cuda可用性
  • qanything_kernel/dependent_server/llm_for_local_serve/llm_server_entrypoint.py:启动大模型服务(模型中转,即调接口的),如果要本地部署,还需要用fastchat启动大模型服务。
  • qanything_kernel/dependent_server/rerank_for_local_serve/rerank_server.py:重排序服务
  • qanything_kernel/dependent_server/ocr_serve/ocr_server.py:ocr服务
  • qanything_kernel/qanything_server/sanic_api.py:核心sanic服务

接口层面,进一步看qanything_kernel\qanything_server\sanic_api.py,直接看这段代码:

app.add_route(document, "/api/docs", methods=['GET'])
app.add_route(new_knowledge_base, "/api/local_doc_qa/new_knowledge_base", methods=['POST'])  # tags=["新建知识库"]
app.add_route(upload_weblink, "/api/local_doc_qa/upload_weblink", methods=['POST'])  # tags=["上传网页链接"]
app.add_route(upload_files, "/api/local_doc_qa/upload_files", methods=['POST'])  # tags=["上传文件"] 
app.add_route(local_doc_chat, "/api/local_doc_qa/local_doc_chat", methods=['POST'])  # tags=["问答接口"] 
app.add_route(list_kbs, "/api/local_doc_qa/list_knowledge_base", methods=['POST'])  # tags=["知识库列表"] 
app.add_route(list_docs, "/api/local_doc_qa/list_files", methods=['POST'])  # tags=["文件列表"]
app.add_route(get_total_status, "/api/local_doc_qa/get_total_status", methods=['POST'])  # tags=["获取所有知识库状态"]
app.add_route(clean_files_by_status, "/api/local_doc_qa/clean_files_by_status", methods=['POST'])  # tags=["清理数据库"]
app.add_route(delete_docs, "/api/local_doc_qa/delete_files", methods=['POST'])  # tags=["删除文件"] 
app.add_route(delete_knowledge_base, "/api/local_doc_qa/delete_knowledge_base", methods=['POST'])  # tags=["删除知识库"] 
app.add_route(rename_knowledge_base, "/api/local_doc_qa/rename_knowledge_base", methods=['POST'])  # tags=["重命名知识库"] 

可以看到,这里的服务接口远比实际想的还要多,这里绝大部分是文档相关的接口,包括文档多个类型的加载查询删除,至于这里类似document、new_knowledge_base的定义,都在隔壁的qanything_kernel\qanything_server\handler.py里面(说实话我个人并不喜欢from XXX import *的模式,写起来简单,但是不利于阅读和后续的开发,包括后面可能重名、文件重复之类的,非常不好找,不过见仁见智因地制宜各有取舍吧)。

__all__ = ["new_knowledge_base", "upload_files", "list_kbs", "list_docs", "delete_knowledge_base", "delete_docs",
           "rename_knowledge_base", "get_total_status", "clean_files_by_status", "upload_weblink", "local_doc_chat",
           "document"]

这就是所有的接口。

比较重要的就是/api/local_doc_qa/local_doc_chat这个问答接口了,在线推理主要就是请求这个来实现的。当然了,这里有关上传文件、链接之类的功能,也非常重要。

4,算法之外的细节

4.1, 算法服务sanic

sanic似乎不是一个新东西了,qanything用的版本,根据requirements使用的是sanic==23.6.0。

  • 官方文档:https://sanic.readthedocs.io/en/stable/

通过这玩意,就能把一个模块包装成服务,供别人随时请求使用了,就这个功能而言,和fastapi(这个的推荐度也比较高)、flask、tornado之类的还是比较类似的。

这里以一个最简单的接口来解释一下。
首先是需要定义一个接口,在qanything项目内就是一个handler,写在qanything_kernel\qanything_server\handler.py里面。这是其中一个最简单的,展示基本文档的接口

from sanic import request
from sanic.response import text as sanic_text

async def document(req: request):
    description = """
# QAnything 介绍
[戳我看视频>>>>>【有道QAnything介绍视频.mp4】](https://docs.popo.netease.com/docs/7e512e48fcb645adadddcf3107c97e7c)

**QAnything** (**Q**uestion and **A**nswer based on **Anything**) 是支持任意格式的本地知识库问答系统。

您的任何格式的本地文件都可以往里扔,即可获得准确、快速、靠谱的问答体验。

**目前已支持格式:**
* PDF
* Word(doc/docx)
* PPT
* TXT
* 图片
* 网页链接
* ...更多格式,敬请期待

# API 调用指南

## API Base URL

https://qanything.youdao.com

## 鉴权
目前使用微信鉴权,步骤如下:
1. 客户端通过扫码微信二维码(首次登录需要关注公众号)
2. 获取token
3. 调用下面所有API都需要通过authorization参数传入这个token

注意:authorization参数使用Bearer auth认证方式

生成微信二维码以及获取token的示例代码下载地址:[微信鉴权示例代码](https://docs.popo.netease.com/docs/66652d1a967e4f779594aef3306f6097)

## API 接口说明
    {
        "api": "/api/local_doc_qa/upload_files"
        "name": "上传文件",
        "description": "上传文件接口,支持多个文件同时上传,需要指定知识库名称",
    },
    {
        "api": "/api/local_doc_qa/upload_weblink"
        "name": "上传网页链接",
        "description": "上传网页链接,自动爬取网页内容,需要指定知识库名称",
    },
    {
        "api": "/api/local_doc_qa/local_doc_chat" 
        "name": "问答接口",
        "description": "知识库问答接口,指定知识库名称,上传用户问题,通过传入history支持多轮对话",
    },
    {
        "api": "/api/local_doc_qa/list_files" 
        "name": "文件列表",
        "description": "列出指定知识库下的所有文件名,需要指定知识库名称",
    },
    {
        "api": "/api/local_doc_qa/delete_files" 
        "name": "删除文件",
        "description": "删除指定知识库下的指定文件,需要指定知识库名称",
    },

"""
    return sanic_text(description)

有了这个接口后,在服务的启动中,增加这个接口即可。

from sanic import Sanic
app = Sanic("QAnything")
app.add_route(document, "/api/docs", methods=['GET'])
 
app.run(host='0.0.0.0', port=8777, workers=10, access_log=False)

这样就完成了一个接口的编写,还是比较简单的。

具体详细的使用方法,包括POST请求、流式等,具体可以详细看看项目,这些都是有的。

4.2,大模型部署

大模型服务这里使用了两种方案:

  • 一种是直接用sanic做中转站的方案
  • 一种是使用fastchat来进行。

先把整块部署代码的启动脚本搬出来:scripts\run_for_local_option.sh,比较长,可以直接翻到最后面看解析。

if [ "$runtime_backend" = "default" ]; then
    echo "Executing default FastTransformer runtime_backend"
    # start llm server
    # 判断一下,如果gpu_id1和gpu_id2相同,则只启动一个triton_server
    if [ $gpu_id1 -eq $gpu_id2 ]; then
        echo "The triton server will start on $gpu_id1 GPU"
        CUDA_VISIBLE_DEVICES=$gpu_id1 nohup /opt/tritonserver/bin/tritonserver --model-store=/model_repos/QAEnsemble --http-port=10000 --grpc-port=10001 --metrics-port=10002 --log-verbose=1 >  /workspace/qanything_local/logs/debug_logs/llm_embed_rerank_tritonserver.log 2>&1 &
        update_or_append_to_env "RERANK_PORT" "10001"
        update_or_append_to_env "EMBED_PORT" "10001"
    else
        echo "The triton server will start on $gpu_id1 and $gpu_id2 GPUs"
 
        CUDA_VISIBLE_DEVICES=$gpu_id1 nohup /opt/tritonserver/bin/tritonserver --model-store=/model_repos/QAEnsemble_base --http-port=10000 --grpc-port=10001 --metrics-port=10002 --log-verbose=1 > /workspace/qanything_local/logs/debug_logs/llm_tritonserver.log 2>&1 &
        CUDA_VISIBLE_DEVICES=$gpu_id2 nohup /opt/tritonserver/bin/tritonserver --model-store=/model_repos/QAEnsemble_embed_rerank --http-port=9000 --grpc-port=9001 --metrics-port=9002 --log-verbose=1 > /workspace/qanything_local/logs/debug_logs/embed_rerank_tritonserver.log 2>&1 &
        update_or_append_to_env "RERANK_PORT" "9001"
        update_or_append_to_env "EMBED_PORT" "9001"
    fi
 
    cd /workspace/qanything_local/qanything_kernel/dependent_server/llm_for_local_serve || exit
    nohup python3 -u llm_server_entrypoint.py --host="0.0.0.0" --port=36001 --model-path="tokenizer_assets" --model-url="0.0.0.0:10001" > /workspace/qanything_local/logs/debug_logs/llm_server_entrypoint.log 2>&1 &
    echo "The llm transfer service is ready! (1/8)"
    echo "大模型中转服务已就绪! (1/8)"
else
    echo "The triton server for embedding and reranker will start on $gpu_id2 GPUs"
    CUDA_VISIBLE_DEVICES=$gpu_id2 nohup /opt/tritonserver/bin/tritonserver --model-store=/model_repos/QAEnsemble_embed_rerank --http-port=9000 --grpc-port=9001 --metrics-port=9002 --log-verbose=1 > /workspace/qanything_local/logs/debug_logs/embed_rerank_tritonserver.log 2>&1 &
    update_or_append_to_env "RERANK_PORT" "9001"
    update_or_append_to_env "EMBED_PORT" "9001"
 
    LLM_API_SERVE_CONV_TEMPLATE="$conv_template"
    LLM_API_SERVE_MODEL="$model_name"
 
    check_folder_existence "$LLM_API_SERVE_MODEL"
 
    update_or_append_to_env "LLM_API_SERVE_PORT" "7802"
    update_or_append_to_env "LLM_API_SERVE_MODEL" "$LLM_API_SERVE_MODEL"
    update_or_append_to_env "LLM_API_SERVE_CONV_TEMPLATE" "$LLM_API_SERVE_CONV_TEMPLATE"
 
    mkdir -p /workspace/qanything_local/logs/debug_logs/fastchat_logs && cd /workspace/qanything_local/logs/debug_logs/fastchat_logs
    nohup python3 -m fastchat.serve.controller --host 0.0.0.0 --port 7800 > /workspace/qanything_local/logs/debug_logs/fastchat_logs/fschat_controller_7800.log 2>&1 &
    nohup python3 -m fastchat.serve.openai_api_server --host 0.0.0.0 --port 7802 --controller-address http://0.0.0.0:7800 > /workspace/qanything_local/logs/debug_logs/fastchat_logs/fschat_openai_api_server_7802.log 2>&1 &
 
    gpus=$tensor_parallel
    if [ $tensor_parallel -eq 2 ]; then
        gpus="$gpu_id1,$gpu_id2"
    else
        gpus="$gpu_id1"
    fi
 
    case $runtime_backend in
    "hf")
        echo "Executing hf runtime_backend"
        
        CUDA_VISIBLE_DEVICES=$gpus nohup python3 -m fastchat.serve.model_worker --host 0.0.0.0 --port 7801 \
            --controller-address http://0.0.0.0:7800 --worker-address http://0.0.0.0:7801 \
            --model-path /model_repos/CustomLLM/$LLM_API_SERVE_MODEL --load-8bit \
            --gpus $gpus --num-gpus $tensor_parallel --dtype bfloat16 --conv-template $LLM_API_SERVE_CONV_TEMPLATE > /workspace/qanything_local/logs/debug_logs/fastchat_logs/fschat_model_worker_7801.log 2>&1 &
 
        ;;
    "vllm")
        echo "Executing vllm runtime_backend"
 
        CUDA_VISIBLE_DEVICES=$gpus nohup python3 -m fastchat.serve.vllm_worker --host 0.0.0.0 --port 7801 \
            --controller-address http://0.0.0.0:7800 --worker-address http://0.0.0.0:7801 \
            --model-path /model_repos/CustomLLM/$LLM_API_SERVE_MODEL --trust-remote-code --block-size 32 --tensor-parallel-size $tensor_parallel \
            --max-model-len 4096 --gpu-memory-utilization $gpu_memory_utilization --dtype bfloat16 --conv-template $LLM_API_SERVE_CONV_TEMPLATE > /workspace/qanything_local/logs/debug_logs/fastchat_logs/fschat_model_worker_7801.log 2>&1 &
        
        ;;
    "sglang")
        echo "Executing sglang runtime_backend"
        ;;
    *)
        echo "Invalid runtime_backend option"; exit 1
        ;;
    esac
fi

先忽略这里有关rank之类模型部署的内容。

  • 首先是sanic方案(20 行),qanything_kernel\dependent_server\llm_for_local_serve\llm_server_entrypoint.py里面,这只是一个大模型中转服务,内部只是在请求QwenTritonModel,调用的逻辑在qanything_kernel\dependent_server\llm_for_local_serve\modeling_qwen.py,不过在代码内没有找到具体模型部署的代码,从请求代码来看,像是有一个grpc接口。
  • 然后是fastchat方案,在else下(40行),代码比较详尽的是runtime_backend为hf和vllm的模式。具体的部署,都是围绕着fastchat进行的(https://github.com/lm-sys/FastChat),这个工具目前看还比较方便的,直接命令式就能做了。

4.3,小模型部署

这里涉及的小模型还不少。

首先是向量模型排序模型,基本的模式都是triton启服务,然后再启一个服务做中转,至少向量模型和排序模型都是,类似下面这样

CUDA_VISIBLE_DEVICES=$gpu_id2 nohup /opt/tritonserver/bin/tritonserver --model-store=/model_repos/QAEnsemble_embed_rerank --http-port=9000 --grpc-port=9001 --metrics-port=9002 --log-verbose=1 > /workspace/qanything_local/logs/debug_logs/embed_rerank_tritonserver.log 2>&1 &
nohup python3 -u qanything_kernel/dependent_server/rerank_for_local_serve/rerank_server.py > /workspace/qanything_local/logs/debug_logs/rerank_server.log 2>&1 &

rerank_server后面会请求grpc服务,具体的请求则写在了qanything_kernel\dependent_server\rerank_for_local_serve\rerank_server_backend.py里面。

比较特殊的是OCR模型,内部用的是PaddleOCR,这个直接包了层sanic服务来实现的。

CUDA_VISIBLE_DEVICES=$gpu_id2 nohup python3 -u qanything_kernel/dependent_server/ocr_serve/ocr_server.py > /workspace/qanything_local/logs/debug_logs/ocr_server.log 2>&1 &

4.4,中间件

  • 首先是向量库milvus(https://milvus.io/),也支持python(pymilvus==2.3.4)。在qanything的代码中,给出了一个比较完整的客户端使用组件(qanything_kernel\connector\database\milvus\milvus_client.py),这个工具写的很完整,健壮性也很高,仔细研读和使用的可靠性都很高。
  • 至于ES,也就是elasticsearch(项目中用的版本应该是8.11.4),应该是做搜索引擎的鼻祖了,这已经非常成熟,同样支持python客户端的(pip install elasticsearch),qanything_kernel\connector\database\milvus\es_client.py是一个不错的工具,此处ES主要用于字面的检索,在milvus_client.py中有提及字面和向量混合搜索的功能,默认是只支持向量检索,如果要混合检索,就会请求一次ES。
def __search_emb_sync(self, embs, expr='', top_k=None, client_timeout=None, queries=None):
    if not top_k:
        top_k = self.top_k
    milvus_records = self.sess.search(data=embs, partition_names=self.kb_ids, anns_field="embedding",
                                        param=self.search_params, limit=top_k,
                                        output_fields=self.output_fields, expr=expr, timeout=client_timeout)
    milvus_records_proc = self.parse_batch_result(milvus_records)
    # debug_logger.info(milvus_records)
 
    # 混合检索
    if self.hybrid_search:
        es_records = self.client.search(queries) # 补一个client的定义:self.client = ElasticsearchClient(index_name=self.index_name)
        es_records_proc = self.parse_es_batch_result(es_records, milvus_records)
        milvus_records_proc.extend(es_records_proc)
 
    return milvus_records_proc

值得提醒的是,ES在比较新的版本其实也支持构造向量索引了(也就是支持向量召回了),此处还使用milvus应该有别的原因吧。

最后就是mysql了,mysql在这里主要是起到了记录文档、知识管理、用户管理等作用,保持数据的一致性,核心代码在qanything_kernel\connector\database\mysql\mysql_client.py,这里的mysql没有做一个通用组件,而是直接定制化了一个类KnowledgeBaseManager,直接做文档、知识等信息的总结。


补充:
深入了解grpc(一):grpc介绍
什么是 gRPC?怎么进行调试?

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

苹果电脑废纸篓数据被清空了,有什么方法可以恢复吗?

使用电脑的用户都知道,被删除的文件一般都会经过回收站,想要恢复它直接点击“还原”就可以恢复到原始位置。mac电脑同理也是这样,但是“回收站”在mac电脑显示为“废纸篓”。 苹果电脑废纸篓数据被清空了,有什么方法可以恢复吗&am…

页面速度是如何影响SEO的?

搜索引擎使用复杂的算法来衡量您网站的重要方面,以决定是否向您发送流量。 搜索引擎使用您网站的小元素来确定您网站的质量和真实性,然后此操作将转化为您的网页在搜索引擎结果页面 中出现的位置。提高您在 SERP 中的排名的过程称为搜索引擎优化 (SEO)。…

在 Mac 上使用 本地 LLM 文本终结

我们可使用本地大型语言模型,如Mistral、Llama等,来给文本做总结,相比在线的 Kimi ,ChatGPT, 我们不用担心数据泄露,因为整个操作都是在本地电脑完成的。 我们用 ollama 举例 首先安装 ollama https://ol…

从零搭建Prometheus到Grafana告警推送

目录 一、Prometheus源码安装和动态更新配置 二、Prometheus操作面板和常见配置 三、Prometheus常用监控组件exporter配置 3.1 exporter是什么 3.2 有哪些exporter 3.3 exporter怎么用 3.4 实战 node_exporter ​3.5 其它exporter都怎么用 四、Promethus整合新版Sprin…

数据结构常见图算法

深度优先搜索 时间复杂度 领接矩阵表示 O( n2) 领接表表示 O(n+e) 空间复杂度 O(e) DFS与回溯法类似,一条路径走到底后需要返回上一步,搜索第二条路径。在树的遍历中,首先一直访问到最深的节点,然后回溯到它的父节点,遍历另一条路径,直到遍历完所有节点…

怎样在《语文世界》期刊上发表论文?

怎样在《语文世界》期刊上发表论文? 《语文世界》知网国家级 1.5-2版 2500字符左右 正常收25年4-6月版面 可加急24年内(初中,高中,中职,高职,大学均可,操作周期2个月左右) 《语文世…

【CH32V305FBP6】USBD HS 虚拟串口分析

文章目录 前言分析端点 0USBHS_UIS_TOKEN_OUT 端点 2USBHS_UIS_TOKEN_OUTUSBHS_UIS_TOKEN_IN 前言 虚拟串口,端口 3 单向上报,端口 2 双向收发。 分析 端点 0 USBHS_UIS_TOKEN_OUT 设置串口参数: 判断 USBHS_SetupReqCode CDC_SET_LIN…

解锁应用商店新玩法:Xinstall渠道包,让你的App推广效率飙升

在移动应用竞争日益激烈的今天,如何在众多应用商店中脱颖而出,实现精准推广与高效获客,成为每位App开发者与广告主的共同追求。幸运的是,Xinstall作为一款一站式App全渠道统计服务商,以其专业的渠道包解决方案&#xf…

Yi-1.5 9B Chat 上线Amazon SageMaker JumpStart

你是否对简单的API调用大模型感到不满足?是否因为无法亲自部署属于自己的大模型而烦恼? 好消息来了,Amazon SageMaker JumpStart 初体验 CloudLab实验上线啦! 本实验将以零一万物最新发布的中文基础模型 Yi-1.5 9B Chat 为例&am…

如何指定Microsoft Print To PDF的输出路径

在上一篇文章中,介绍了三种将文件转换为PDF的方式。默认情况下,在Microsoft Print To PDF的首选项里,是看不到输出路径的设置的。 需要一点小小的手段。 运行输入 control 打开控制面板,选择硬件和声音下的查看设备和打印机 找到…

在卷积神经网络(CNN)中为什么可以使用多个较小的卷积核替代一个较大的卷积核,以达到相同的感受野

在卷积神经网络(CNN)中为什么可以使用多个较小的卷积核替代一个较大的卷积核,以达到相同的感受野 flyfish 在卷积神经网络(CNN)中,可以使用多个较小的卷积核替代一个较大的卷积核,以达到相同的…

探索大型语言模型自动评估 LLM 输出长句准确性的方法

LLM现在能够自动评估较长文本中的事实真实性 源码地址:https://github.com/google-deepmind/long-form-factuality 论文地址:https://arxiv.org/pdf/2403.18802.pdf 这篇论文是关于谷歌DeepMind的,提出了新的数据集、评估方法和衡量标准&am…

一篇文章搞懂时间复杂度和空间复杂度

不知道小伙伴们有没有刷过力扣上的算法题,我在上研究生的时候,刷过了前40道题,上面的算法题,我觉得还挺难的,当你写完代码的时候,就可以提交自己写的代码到系统上,系统会给你写的代码计算时间复…

嵌入式c语言1——gcc以及linux嵌入式

GCC全名GNU Complier Collection,是一个开源的程序语言解释器,运行在linux系统中 对以程序名后缀结尾源代码文件,gcc可以做解释并生成可执行文件

uniapp做小程序内打开地图展示位置信息

使用场景&#xff1a;项目中需要通过位置信息打开地图查看当前位置信息在地图那个位置&#xff0c;每个酒店有自己的经纬度和详细地址&#xff0c;点击地图按钮打开内置地图如图 方法如下&#xff1a; <view class"dttu" click"openMap(info.locationY,info.…

解决Linux环境Qt报“cannot find -lgl“问题

今天&#xff0c;在Ubuntu 18.04.6环境下&#xff0c;安装Qt5.14.2之后&#xff0c;运行一个QWidget工程&#xff0c;发现Qt报"cannot find -lgl"错误。     出现这种现象的原因&#xff1a;Qt的Path路径没有配置&#xff0c;缺少libqt4-dev依赖包和一些必要的组件…

128陷阱详解

人不走空 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌赋&#xff1a;斯是陋室&#xff0c;惟吾德馨 目录 &#x1f308;个人主页&#xff1a;人不走空 &#x1f496;系列专栏&#xff1a;算法专题 ⏰诗词歌…

基于机器学习的永磁同步电机矢量控制策略-高分资源-下载可用!

基于机器学习的永磁同步电机矢量控制策略 优势 训练了RL-Agent&#xff0c;能够提高电机在非线性负载下的性能。 部分程序 仿真结果 转矩估计及dq轴电流。 代码有偿&#xff0c;50&#xff0c;需要的可以联系。

Vue前端练习

此练习项目只涉及前端&#xff0c;主要是vue和ElementUI框架的使用。&#xff08;ElementUI官网&#xff1a;Element - The worlds most popular Vue UI framework&#xff09; 一、环境准备 安装idea 安装Node.js 一键式安装(不需要做任何配置) npm -v&#xff08;也可用nod…

C语言 | Leetcode C语言题解之第198题打家劫舍

题目&#xff1a; 题解&#xff1a; int rob(int* nums, int numsSize){// dp0: 不偷这个屋子能窃到的最高金额int dp0 0;// dp1: 偷这间屋子能窃到的最高金额int dp1 nums[0];for (int i 1; i < numsSize; i) {int dp0new fmax(dp0, dp1);int dp1new dp0 nums[i];dp…