QAnything-1.3.0,支持纯python笔记本运行,支持混合检索

QAnything 1.3.0 更新了,这次带来两个主要功能,一个是纯python的安装,另一个是混合检索。更多详情见:

https://github.com/netease-youdao/QAnything/releases

纯python安装

我们刚发布qanything开源的时候,希望用户可以用这个代码来直接在生产环境中部署使用,为了性能,它引入了很多第三方的库和服务,比如milvus,mysql,tritonserver,elasticsearch等。这些服务本身也非常庞大复杂,我们做了docker镜像和dockerfiles,试图将一些依赖打包起来,用户只要拉下来就可以用。但是还是有很多人遇到麻烦。比如不能在mac等笔记本上运行。

所以这次,这次我们发布了一个纯python的轻量级的版本,可以在mac等笔记本上跑起来,可以不依赖gpu。安装过程极其简单:

第一步:拉代码到本地

git clone https://github.com/netease-youdao/QAnything

如果是国内的访问不了github的,可以用gitee,我们已经同步了代码。

git clone https://gitee.com/netease-youdao/QAnything.git

第二步:安装

首先需要将代码分支切换到develop_for_v1.3.1的版本(因为这个版本还在开发中),然后执行安装:

cd QAnythinggit checkout develop_for_v1.3.1pip install -e . 

在这一步,系统会自动检测所有依赖的东西,包括vllm,transformer,pytorch等库。为了提高国内用户的下载速度,里面大部分的源都已经针对国内环境做了优化。

注意,如果是Mac下,需要先安装xcode(在mac app store上可以找到),因为它依赖了lamma.cpp,需要编译一下。

第三步:使用

为了方便用户使用,我们在scripts下面放了针对多个机器环境配置的一键启动的脚本:​​​​​​​

ls scripts/base_run.sh                                    run_for_4B_in_M1_mac.shgpu_capabilities.json                          run_for_7B_in_Linux_or_WSL.shlist_files.py                                  run_for_7B_in_M1_mac.shlocal_chat_qa.py                               run_for_openai_api_in_M1_mac.shmulti_local_chat_qa.py                         run_for_openai_api_with_cpu_in_Linux_or_WSL.shmulti_upload_files.py                          run_for_openai_api_with_gpu_in_Linux_or_WSL.shmysql_statics.py                               stream_chat.pynew_knowledge_base.py                          upload_files.pynvidia_gpus_compute_capability.py              weixiaobao.jpgrun_for_3B_in_Linux_or_WSL.sh

以笔者的电脑为例(mac m1),我可以选择用:

scripts/run_for_openai_api_in_M1_mac.sh

这个脚本使用了本地的embedding/rerank/ocr,但是得配置一下openai的接口。这个需要大家找一下,有很多代理openai的接口,可以配置baseurl和key。

假设我们已经配置好了,就可以通过这个脚本(我隐去了里面的url和key,用*替代)启动qanything了:​​​​​​​

(base) mac:QAnything linhui$ sh scripts/run_for_openai_api_in_M1_mac.shXcode 已正确安装在路径:/Applications/Xcode.app/Contents/Developer即将启动后端服务,启动成功后请复制[http://127.0.0.1:8777/qanything/]到浏览器进行测试。运行qanything-server的命令是:python3 -m qanything_kernel.qanything_server.sanic_api --host 127.0.0.1 --port 8777 --model_size 7B  --use_openai_api --openai_api_base https://api.openai****.org/v1 --openai_api_key sk-AM3*************BHl --openai_api_model_name gpt-3.5-turbo-1106 --openai_api_context_length 4096 --workers 4LOCAL DATA PATH: /Users/linhui/workspace/QAnything/QANY_DB/contentLOCAL_RERANK_REPO: maidalun/bce-reranker-base_v1LOCAL_EMBED_REPO: maidalun/bce-embedding-base_v1<Logger debug_logger (INFO)> <Logger qa_logger (INFO)>llama_cpp_python 0.2.57 已经安装。2024-04-08 10:03:13,141 - modelscope - INFO - PyTorch version 2.2.1 Found.2024-04-08 10:03:13,141 - modelscope - INFO - Loading ast index from /Users/linhui/.cache/modelscope/ast_indexer2024-04-08 10:03:13,176 - modelscope - INFO - Loading done! Current index file version is 1.13.0, with md5 4e15c4f2db78c84e863a425f008f4eac and a total number of 972 components indexeduse_cpu: Falseuse_openai_api: True[2024-04-08 10:03:14 +0800] [20092] [INFO]   ┌─────────────────────────────────────────────────────────────────────────────┐  │                                Sanic v23.6.0                                │  │                      Goin' Fast @ http://127.0.0.1:8777                     │  ├───────────────────────┬─────────────────────────────────────────────────────┤  │                       │     mode: production, w/ 4 workers                  │  │     ▄███ █████ ██     │   server: sanic, HTTP/1.1                           │  │    ██                 │   python: 3.10.9                                    │  │     ▀███████ ███▄     │ platform: macOS-13.3.1-arm64-arm-64bit              │  │                 ██    │ packages: sanic-routing==23.12.0, sanic-ext==23.6.0 │  │    ████ ████████▀     │                                                     │  │                       │                                                     │  │ Build Fast. Run Fast. │                                                     │  └───────────────────────┴─────────────────────────────────────────────────────┘
[2024-04-08 10:03:14 +0800] [20092] [WARNING] Sanic is running in PRODUCTION mode. Consider using '--debug' or '--dev' while actively developing your application.LOCAL DATA PATH: /Users/linhui/workspace/QAnything/QANY_DB/contentLOCAL_RERANK_REPO: maidalun/bce-reranker-base_v1LOCAL_EMBED_REPO: maidalun/bce-embedding-base_v1<Logger debug_logger (INFO)> <Logger qa_logger (INFO)>llama_cpp_python 0.2.57 已经安装。2024-04-08 10:03:17,231 - modelscope - INFO - PyTorch version 2.2.1 Found.2024-04-08 10:03:17,231 - modelscope - INFO - Loading ast index from /Users/linhui/.cache/modelscope/ast_indexer2024-04-08 10:03:17,264 - modelscope - INFO - Loading done! Current index file version is 1.13.0, with md5 4e15c4f2db78c84e863a425f008f4eac and a total number of 972 components indexeduse_cpu: Falseuse_openai_api: TrueLOCAL DATA PATH: /Users/linhui/workspace/QAnything/QANY_DB/contentLOCAL_RERANK_REPO: maidalun/bce-reranker-base_v1LOCAL_EMBED_REPO: maidalun/bce-embedding-base_v1<Logger debug_logger (INFO)> <Logger qa_logger (INFO)>LOCAL DATA PATH: /Users/linhui/workspace/QAnything/QANY_DB/contentLOCAL_RERANK_REPO: maidalun/bce-reranker-base_v1LOCAL_EMBED_REPO: maidalun/bce-embedding-base_v1<Logger debug_logger (INFO)> <Logger qa_logger (INFO)>LOCAL DATA PATH: /Users/linhui/workspace/QAnything/QANY_DB/contentLOCAL_RERANK_REPO: maidalun/bce-reranker-base_v1LOCAL_EMBED_REPO: maidalun/bce-embedding-base_v1LOCAL DATA PATH: /Users/linhui/workspace/QAnything/QANY_DB/contentLOCAL_RERANK_REPO: maidalun/bce-reranker-base_v1LOCAL_EMBED_REPO: maidalun/bce-embedding-base_v1<Logger debug_logger (INFO)> <Logger qa_logger (INFO)><Logger debug_logger (INFO)> <Logger qa_logger (INFO)>llama_cpp_python 0.2.57 已经安装。llama_cpp_python 0.2.57 已经安装。llama_cpp_python 0.2.57 已经安装。llama_cpp_python 0.2.57 已经安装。2024-04-08 10:03:21,898 - modelscope - INFO - PyTorch version 2.2.1 Found.2024-04-08 10:03:21,898 - modelscope - INFO - PyTorch version 2.2.1 Found.2024-04-08 10:03:21,898 - modelscope - INFO - Loading ast index from /Users/linhui/.cache/modelscope/ast_indexer2024-04-08 10:03:21,898 - modelscope - INFO - Loading ast index from /Users/linhui/.cache/modelscope/ast_indexer2024-04-08 10:03:21,947 - modelscope - INFO - Loading done! Current index file version is 1.13.0, with md5 4e15c4f2db78c84e863a425f008f4eac and a total number of 972 components indexed2024-04-08 10:03:21,951 - modelscope - INFO - Loading done! Current index file version is 1.13.0, with md5 4e15c4f2db78c84e863a425f008f4eac and a total number of 972 components indexed2024-04-08 10:03:22,335 - modelscope - INFO - PyTorch version 2.2.1 Found.2024-04-08 10:03:22,336 - modelscope - INFO - Loading ast index from /Users/linhui/.cache/modelscope/ast_indexer2024-04-08 10:03:22,369 - modelscope - INFO - Loading done! Current index file version is 1.13.0, with md5 4e15c4f2db78c84e863a425f008f4eac and a total number of 972 components indexed2024-04-08 10:03:22,431 - modelscope - INFO - PyTorch version 2.2.1 Found.2024-04-08 10:03:22,432 - modelscope - INFO - Loading ast index from /Users/linhui/.cache/modelscope/ast_indexer2024-04-08 10:03:22,466 - modelscope - INFO - Loading done! Current index file version is 1.13.0, with md5 4e15c4f2db78c84e863a425f008f4eac and a total number of 972 components indexeduse_cpu: Falseuse_openai_api: Trueuse_cpu: Falseuse_openai_api: True[2024-04-08 10:03:22 +0800] [20102] [INFO] Sanic Extensions:[2024-04-08 10:03:22 +0800] [20102] [INFO]   > injection [0 dependencies; 0 constants][2024-04-08 10:03:22 +0800] [20102] [INFO]   > openapi [http://127.0.0.1:8777/docs][2024-04-08 10:03:22 +0800] [20102] [INFO]   > http [2024-04-08 10:03:22 +0800] [20102] [INFO]   > templating [jinja2==3.1.2][2024-04-08 10:03:22 +0800] [20099] [INFO] Sanic Extensions:[2024-04-08 10:03:22 +0800] [20099] [INFO]   > injection [0 dependencies; 0 constants][2024-04-08 10:03:22 +0800] [20099] [INFO]   > openapi [http://127.0.0.1:8777/docs][2024-04-08 10:03:22 +0800] [20099] [INFO]   > http [2024-04-08 10:03:22 +0800] [20099] [INFO]   > templating [jinja2==3.1.2]use_cpu: Falseuse_openai_api: True[2024-04-08 10:03:23 +0800] [20101] [INFO] Sanic Extensions:[2024-04-08 10:03:23 +0800] [20101] [INFO]   > injection [0 dependencies; 0 constants][2024-04-08 10:03:23 +0800] [20101] [INFO]   > openapi [http://127.0.0.1:8777/docs][2024-04-08 10:03:23 +0800] [20101] [INFO]   > http [2024-04-08 10:03:23 +0800] [20101] [INFO]   > templating [jinja2==3.1.2]use_cpu: Falseuse_openai_api: True[2024-04-08 10:03:23 +0800] [20100] [INFO] Sanic Extensions:[2024-04-08 10:03:23 +0800] [20100] [INFO]   > injection [0 dependencies; 0 constants][2024-04-08 10:03:23 +0800] [20100] [INFO]   > openapi [http://127.0.0.1:8777/docs][2024-04-08 10:03:23 +0800] [20100] [INFO]   > http [2024-04-08 10:03:23 +0800] [20100] [INFO]   > templating [jinja2==3.1.2]

然后就可以通过浏览器访问:http://127.0.0.1:8777/qanything/#/home 来体验qanything了。

当然,也可以使用本地的大模型,qanything已经通过lamma.cpp以及vllm 集成了多个本地大模型。在mac的笔记本上是千问7b和4b的int4的量化版本,我测试了感觉效果一般。在linux + nvidia显卡上用的是千问7b的int8的版本,效果还行。

目前python版(develop_v1.3.1分支)相比docker版本(master 分支)在易用性上有优势,但是一些性能相关的东西还没有迁移过来,比如docker版本支持tensortllm,推理性能更高一些。docker版本里面的ocr解析模型质量也略好点。

混合检索

这次我们同时支持了混合检索 BM25 + embedding。

图片

embedding语义检索

qanything自带了bcembedding的模型,可以做语义检索,大部分情况下已经能取得比较好的效果。

BM25关键字搜索

在实际使用中,我们发现有一些特殊情况用关键字搜索效果会更好,包括:

  1. 特定名字的搜索。比如iphone 15。如果用向量检索可能会把所有的iphone都给检索出来了,而我只要iphone 15这个型号的。

  2. 罕见的短词、缩略词搜索。这个因为训练语料中见的很少,可能会导致语义理解发生偏差,检索不出来。

  3. 一些id的检索。需要做精确匹配的。

BM25算法的解释

BM25算法是比较经典的关键字搜索算法,它是由tf/idf算法改进而来的。2016年Elasticsearch 5.0的默认检索器从tf/idf改成了bm25算法。这里简单科普下这个算法:

tf/idf算法

搜索query和doc的匹配度的score计算公式为:

score(D, T) = tf * idf = termFrequency(D, T) * log(N / docFrequency(T))

其中 termFrequency 是词频,代表query的词在某个文档中出现的次数,出现的越多次就越相关。idf代表这个词的区分度,如果一个词(比如“的”、“地”、“得”之类副词)在很多文档都出现,这种词就不太重要。N是文档总数,docFrequency代表这个词在多少个文档中出现。其中Log是为了平滑,否则细微的docFrequency的变化会导致score的剧烈波动。

BM25算法

图片

bm25算法在tf/idf算法上做了几点改进:

1.词频贡献有个上限。比如一个文档出现了太多次query里面的某个词了,这个贡献不应一直累加,而是有个上限。所以它用tf/(tf+k) 来做抑制。这带来的一个好处是,算法会青睐不同query的词同时在文档中出现的情况。比如,搜索 cat dog,如果cat 和 dog都在文档中出现1次,它的分值会比只有dog在文档中出现2次的分值要高。如果k=1的话,一个词出现两次的score=1/2,两个词出现1次的socre = 2/3。

2. 惩罚长文档的影响力。如果文档词比较多,那么命中关键字的可能性当然就大很多。把 |D|/(avg doc length)作为k,可以达到这个目的。

3. 词的重要性。这个还是按idf的那套策略来算。这里用的是log (N-DF+.5)/(DF+.5),这是由学术理论算出来的最优值(在一些简化的假设条件下)。

重排序(rerank)

两路检索出来的的chunks要按照重要性做重新排序。重排序也有多种算法,比如基于倒数的融合排序:

图片

不过在我们系统中,我们直接依赖BCE rerank做重排序,在各种场景下表现良好。

混合检索当前还只在docker版本(master 分支) 上支持。

qanything 1.3.0的更新

新特性

  1. 支持在纯Python环境中安装,可以在MAC上运行,也可以在纯CPU机器上运行。详见:纯Python环境安装教程

  2. 支持混合检索(BM25+Embedding)。

  3. 当系统命令缺失时,下载提示更清晰。

  4. 自动检测显卡的计算能力和内存大小,并根据情况自动调整默认启动参数,以提供用户最佳体验,并给予相关提示。

  5. 更新前置条件,最低支持 GTX1050Ti,支持更多显卡型号。

  6. 提示用户代码仓库是否为最新,仅适用于主分支。

  7. 优化启动流程,自动查询相关日志并在前端显示错误消息,避免连续输出 'waiting for coffee'。

  8. 在前端添加英文版本。

  9. 修复已知的错误,优化用户体验。(在 Milvus 插入失败时,请记得删除根目录下的 "volumes" 文件夹。)

变更内容

  • 修复启动脚本已知问题。由 @xixihahaliu 提交于 #92

  • 修复已知问题,优化用户体验。由 @xixihahaliu 提交于 #102

  • Milvus增加用户名、密码、数据库名支持。由 @cklogic 提交于 #97

  • feat_#114: 为 NVIDIA GeForce RTX 4090D 添加 GPU 兼容性检查。由 @johnymoo 提交于 #115

  • 修复:由 @pinkcxy 提交的轮次控制问题。#131

  • 问题修复:调用api/api/local_doc_qa/local_doc_chat返回数据为None。由 @leehom0123 提交于 #137

  • 优化解析 csv 和 xlsx 文件的逻辑。此外,现在支持离线运行 Docker 镜像。由 @xixihahaliu 提交于 #139

  • 混合搜索。由 @shenlei1020 提交于 #194

QAnything开源代码地址:

https://github.com/netease-youdao/QAnything

更多信息见:

  1. 纯python的安装说明:https://github.com/netease-youdao/QAnything/blob/qanything-python-v1.3.1/README.md#pure-python-environment-installation-guide

  2. bce embedding 和 rerank: https://github.com/netease-youdao/BCEmbedding

  3. bm25算法的解释:https://kmwllc.com/index.php/2020/03/20/understanding-tf-idf-and-bm-25/

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

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

相关文章

冯喜运:4.8晚间黄金原油走势分析及操作建议

黄金走势分析&#xff1a;      金价在亚洲大国市场开盘后突然飙升约30美元至历史新高&#xff0c;触发了交易员的积极反应。这一行情主要是因为亚洲大国央行持续增加黄金储备的预期所致&#xff0c;而且市场对全球央行今年可能的大规模黄金购买提前建立了多头头寸。数据显…

数据转换 | Matlab基于GADF格拉姆角差场一维数据转二维图像方法

目录 效果分析基本介绍程序设计参考资料获取方式 效果分析 基本介绍 GADF&#xff08;Gramian Angular Difference Field&#xff09;是一种将时间序列数据转换为二维图像的方法之一。它可以用于提取时间序列数据的特征&#xff0c;并可应用于各种领域&#xff0c;如时间序列分…

【深入理解Java IO流0x05】Java缓冲流:为提高IO效率而生

1. 引言 我们都知道&#xff0c;内存与硬盘的交互是比较耗时的&#xff0c;因此适当得减少IO的操作次数&#xff0c;能提升整体的效率。 Java 的缓冲流是对字节流和字符流的一种封装&#xff08;装饰器模式&#xff0c;关于IO流中的一些设计模式&#xff0c;后续会再出博客来讲…

详解简单的shell脚本 --- 命令行解释器【Linux后端开发】

首先附上完整代码 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/wait.h> //命令行解释器 //shell 运行原理&#xff1a;通过让子进程执行命令&#xff0c;父进…

谷歌浏览器插件开发速成指南:弹窗

诸神缄默不语-个人CSDN博文目录 本文介绍谷歌浏览器插件开发的入门教程&#xff0c;阅读完本文后应该就能开发一个简单的“hello world”插件&#xff0c;效果是出现写有“Hello Extensions”的弹窗。 作为系列文章的第一篇&#xff0c;本文还希望读者阅读后能够简要了解在此基…

电影特效渲染为什么费时间?「瑞云渲染」

影视特效渲染过程通常耗时且资源密集&#xff0c;因为它涉及处理复杂的视觉元素和光影效果。瑞云渲染通过云技术提供解决方案&#xff0c;加快渲染速度并降低成本。简而言之&#xff0c;电影特效渲染之所以费时&#xff0c;是因为其对计算机资源的高需求。 电影特效渲染费时间原…

Redis的三种部署方案

文章目录 单机模式主从复制哨兵模式分片集群 在Redis中提供的集群方案总共有三种&#xff1a;单机模式&#xff0c;主从复制集群、哨兵模式&#xff0c;Redis分片集群 单机模式 Redis 只运行在一台服务器上&#xff0c;并且所有的数据都存储在这一台服务器的内存中。 主从复制…

Django之REST Client插件

一、接口测试工具介绍 在开发前后端分离项目时,无论是开发后端,还是前端,基本都是需要测试API接口的内容,而目前我们需要开发遵循RESTFul规范的项目,也是必然的(自己不开发前端页面)。 在网上有很多这样的工具,常用的postman,但还是需要下载安装。在这我们介绍一个VSCod…

【小白学机器学习12】假设检验之3:t 检验 (t检验量,t分布,查t值表等)

目录 1 t 检验的定义 1.1 来自维基百科和百度百科 1.2 别名 1.3 和其他检验的区别 2 适用情况&#xff1a; 2.1 关于样本情况 2.2 适合检查的情况 2.2.1 单样本均值检验&#xff08;One-sample t-test&#xff09; 2.2.2 两独立样本均值检验&#xff08;Independent …

hydra九头蛇

一、hydra简介 Hydra是一款非常强大的暴力破解工具&#xff0c;它是由著名的黑客组织THC开发的一款开源暴力破解工具。Hydra是一个验证性质的工具&#xff0c;主要目的是&#xff1a;展示安全研究人员从远程获取一个系统认证权限。 目前该工具支持以下协议的爆破&#xff1a; A…

【网站项目】农业信息管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

[C#]OpenCvSharp改变图像的对比度和亮度

目的 访问像素值mat.At<T>(y,x) 用0初始化矩阵Mat.Zeros 饱和操作SaturateCast.ToByte 亮度和对比度调整 g(x)αf(x)β 用α(>0)和β一般称作增益(gain)和偏置(bias)&#xff0c;分别控制对比度和亮度 把f(x)看成源图像像素&#xff0c;把g(x)看成输出图像像素…

身份证实名认证接口的价格一般是多少呢?基于PHP身份核验接口

身份证实名认证接口分为身份证二要素、三要素、三要素人像核验接口&#xff0c;被广泛的应用于婚恋、交友、电商等等一系列行业领域&#xff0c;身份证实名认证需要实时数据&#xff0c;对于数据源来说也需要可靠&#xff0c;那么&#xff0c;身份证实名认证的价格是不是很贵呢…

小小算式(1 + 2) * (3 + 4)背后的大道理

目录 前缀表示法&#xff08;波兰表达式&#xff09; 中缀表达法 后缀表达法&#xff08;逆波兰表达式&#xff09; 三种表达法的相互转换 练习&#xff1a;逆波兰表达式求值 前缀表示法&#xff08;波兰表达式&#xff09; 波兰表示法&#xff08;英语&#xff1a;Polis…

Python学习,记录不熟悉知识点

目录 Set&#xff08;集合&#xff09; 集合内置方法完整列表 根据字符串的表达式计算结果 ​编辑 条件控制&#xff1a; if – elif – else match...case 循环语句&#xff1a; while循环 for循环 在同一行中有多个赋值操作&#xff08;先计算&#xff0c;再赋值&…

【Vue】Vue3中的OptionsAPI与CompositionAPI

文章目录 OptionsAPICompositionAPI对比总结 OptionsAPI 中文名:选项式API通过定义methods,computed,watch,data等属性方法&#xff0c;处理页面逻辑。以下是OptionsAPI代码结构 实例代码: <script lang"ts">// js或者tsimport { defineComponent } from vu…

javaScript手写专题——防抖/节流/闭包/Promise/深浅拷贝

目录 目录 一、 防抖/节流/闭包/定时器 编写一个组件&#xff0c;在input中输入文本&#xff0c;在给定的数据中查找相关的项目&#xff0c;并渲染搜索结果列表 1.新增InputSearch.vue组件 key的作用 2.新增 InputView.vue 3.添加路由 4.效果演示 follow up加上防抖怎么处理 1.…

「51媒体网」邀请媒体采访报道对企业宣传有何意义?

传媒如春雨&#xff0c;润物细无声的&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 邀请媒体采访报道对企业宣传具有多重意义&#xff1a; 提升品牌知名度和曝光度&#xff1a;媒体是信息传播的重要渠道&#xff0c;通过媒体的报道&#xff0c;企业及其活动、产品能够迅…

软考信息处理技术员2024年5月报名流程及注意事项

2024年5月软考信息处理技术员报名入口&#xff1a; 中国计算机技术职业资格网&#xff08;http://www.ruankao.org.cn/&#xff09; 2024年软考报名时间暂未公布&#xff0c;考试时间上半年为5月25日到28日&#xff0c;下半年考试时间为11月9日到12日。不想错过考试最新消息的…

Sketch是免费软件吗?这款软件支持导入!

Sketch 是一款针对网页、图标、插图等设计的矢量绘图软件。Sketch 的操作界面非常简单易懂&#xff0c;帮助全世界的设计师创作出许多不可思议的作品。但是同时&#xff0c;Sketch 也有一些痛点&#xff1a;使用 Sketch 需要安装 InVision、Abstract 、Zeplin 等插件&#xff0…