理论都懂,却从未在真实场景中实践过你的代码?参与开源项目,可以帮你提升代码能力,解决实际需求。小编为你推荐五个优质的开源项目,从易到难进行介绍,并邀请了 Milvus 学生贡献者谈谈他参与开源项目的感受,一起来看看吧!
项目推荐
01
OI Wiki:Wiki of OI / ICPC for Everyone
OI Wiki 是一个开源的编程竞赛知识整合站点,提供有趣实用的编程竞赛知识以及其他有帮助的内容,帮助广大编程竞赛爱好者更快更深入地学习编程竞赛。目前 OI Wiki 在前端渲染、在线编辑、在线运行等方面还有很多升级的需求,如果你具备前端开发的基础知识,并能够使用 git 进行协作开发,你就可以参与到这个「大型游戏线上攻略,内含炫酷算术魔法」的项目中!官网请见:https://oi-wiki.org/
02
My Room in 3D by Bruno Simon
这是前段时间很火的 3D 房间项目(https://my-room-in-3d.vercel.app/),通过右上角的控件,你可以调节**的光效和色彩。这个房间里的很多细节布置都很生动有趣,比如沙发上挂着一只章鱼猫,书架最上面摞了一堆玩具大象,书桌上的咖啡杯还冒着一丝热气,而桌上笔记本电脑中播放的正是这个项目的完整教程(https://www.youtube.com/watch?v=Hm7fdd8TD7Y)。小小一隅,我们可以**开发者 Bruno Simon **中的私人空间。代码地址:https://git**.com/brunosimon/my-room-in-3d 一起来布置自己的温馨小家吧!
03
MindSpore:适用于端边云场景的新型开源深度学习训练/推理框架
MindSpore 是华为开源的新一代 AI 计算框架,为数据科学家和算法工程师提供设计友好、运行高效的开发体验,推动人工智能软硬件应用生态繁荣**。MindSpore 官网提供了丰富的通用场景教程。同时,MindSpore 致力于进一步开发和丰富 AI 软硬件应用生态,推出了面向大众的「1小时入门 AI 开发工程师」课程(https://www.mindspore.cn/news/newschildren?id=354),不需要任何基础即可上手学习。
04
Wechaty:A Conversational AI RPA SDK for Chatbot
开源项目 Wechaty 是一个开源聊天机器人框架 SDK,具有高度封装、高可用的特性,支持 NodeJs、Python、Go 和 Java 等多语言版本,是一个非常稳定且用户量非常庞大的项目,同时配置了完整的 DevOps 体系并**按照 Apache 的**管理技术社区。除了微信以外,Wechaty 支持大部分主流 IM 软件,可以帮助你完成很多自动操作,比如定时发送消息、同步群发消息、通过好友申请等。跟着官网的教程(https://wechaty.js.org/),你就能迅速熟悉它,Wechaty 每年暑期也会给出一些适合学生参与的暑期项目(https://git**.com/wechaty/summer)。
05
Milvus:An Open-source Vector Database for Unstructured Data
Milvus 是一款开源向量数据库,有单机版和分布式两个版本,主要由 C++ 和 go 语言写成。Milvus 不单单是向量检索工具,而是一个强大的向量数据库,具备一整套专为数据科学工作流设计的 API,针对万亿级向量的搜索可达毫秒级;支持流批一体的数据存储和查询;组件高度可扩展、弹性伸缩。目前,这款数据库已经服务了一千多家用户,拥有非常活跃的社区和技术支持,应用场景包括图片检索、音视频检索、商品召回等等。想要迅速上手使用?欢迎参与 Milvus Bootcamp 训练营 https://milvus.io/cn/bootcamp。
每年暑期,Milvus 社区都会携手中科院软件所专为学生办的「开源之夏」活动,为高校学生们**丰富的工程项目,安排导师答疑解惑。这些项目培养并发掘了一批优秀的开发者,我们来一起看看上海交大的沈志同学的成果吧!
Milvus 向量数据库编译优化项目简介
项目名称:Milvus 向量数据库的编译优化
参与学生:沈志,上海交通大学信息与通信工程专业硕士在读
项目导师:Zilliz 软件工程师 Goose
导师评语:沈志同学优化了 Knowhere 的编译,使 Knowhere 可以独立编译,使其依赖的第三方库避免重复编译,使用更现代的 CMake 优化 CMake 代码,使其更简单、可读性更强、可维护性更强。
Milvus 向量数据库的编译优化
项目综述
Milvus 是一款开源的向量数据库,支持针对 TB 级向量的增删改操作和近实时查询,具有高度灵活、稳定可靠以及高速查询等特点。Milvus 集成了 Faiss、NMSLIB、Annoy 等广泛应用的向量索引库,提供了一整套简单直观的 API,可以针对不同场景选择不同的索引类型。此外,Milvus 还可以对标量数据进行过滤,进一步提高了召回率,增强了搜索的灵活性。
Knowhere 是 Milvus 做向量索引和查询的核心 C++ 库,使用 CMake 编译。
本次项目需求是优化 Knowhere 库的编译部分,使得 Knowhere 能独立于 Milvus 进行编译,并优化 Knowhere 第三方库编译流程,**重复编译库情况,提高编译文件可读性。
项目步骤
明确 Knowhere 和 Milvus 交叉编译内容;修改 Knowhere 第三方库编译代码,将 Knowhere 中用到的 Milvus 第三方库独立写到 Knowhere 的编译文件中;改写 knowhere/cmake 下的编译文件,由于该文件将编译选项和第三方库编译耦合,导致编译文件难以阅读和修改;本项目将**文件结构,使编译文件可读性更强。
项目实施
#1 明确 Knowhere 和 Milvus 向量数据库交叉编译内容
Milvus 向量数据库的第三方库编译:
Milvus 向量数据库的第三方库编译可读性比较强,库编译选项定义在 cmake/ThirdPartyPackages.cmake 文件夹下,库的编译位于 thirdparty 文件夹下,每个库的编译文件单独写成 CMakeLists 文件放在 thirdparty 相对应的子文件夹下。
整体编译位于 core/CMakeLists 中,CmakeLists 文件会首先调用 cmake 文件夹下的 .cmake 文件对编译选项进行定义,随后通过 add_subdirectory 引入第三方库的编译文件,具体的第三方库编译由 thirdparty 下的子文件夹进行统筹。
Figure1 Milvus 文件结构
Figure2 Milvus 第三方库编译
Knowhere 的第三方库编译:
相比于 Milvus 向量数据库的编译,Knowhere 的编译集中在 cmake/ ThirdPartyPackagesCore.cmake 文件中,编译文件冗长,阅读困难,库与库之间的依赖表现不明显,不利于用户使用和**。
另外,可以发现 Knowhere 不仅依赖于外层的 log、utils 源码,还依赖 boost_ext、fiu、gtest、google_benchmark 等相关库以及一部分写在 Milvus 向量数据库中的源码。现在 Knowhere 的编译中,会调用父目录下的这部分代码和 Knowhere 中需要编译的对象进行链接,我们在 Knowhere 的文件夹下**了这部分文件并修改 CMakeLists 中的代码,添加对这部分所需库的编译过程。
Figure3 Knowhere 的第三方库编译
Knowhere 中部分对 Milvus 向量数据库的编译库依赖如下:
set (LOG_SRC knowhere/common/Log.cpp${MILVUS_THIRDPARTY_SRC}/easyloggingpp/easylogging++.cc )add_library(index_log STATIC ${LOG_SRC})set_target_properties(index_log PROPERTIES RULE_LAUNCH_COMPILE "")set_target_properties(index_log PROPERTIES RULE_LAUNCH_LINK "")include_directories(${MILVUS_THIRDPARTY_SRC})set(config_srcs knowhere/archive/KnowhereConfig.cpp )
我们对 Knowhere **这部分库的编译内容,使 Knowhere 有能力单独对这部分库进行编译。
Figure4 **前后 Knowhere 文件夹结构,
其中左图是**前 index 目录结构,右图为**后目录结构。
添加编译库代码如下,这里 add_subdirectory 会自动调用该文件夹下的 CMakeLists.txt 内容。
# ****************************** Thirdparty googletest ***************************************if ( KNOWHERE_BUILD_TESTS )if(NOT TARGET gtest) add_subdirectory( gtest ) add_subdirectory( google_benchmark)endif()endif()# ****************************** Thirdparty Arrow ***************************************if(NOT TARGET boost_bitset_ext) add_subdirectory( boost_ext )endif()if(NOT TARGET fiu) add_subdirectory(fiu)endif()
#2 修改 Knowhere 第三方库编译代码以避免重复编译情况
Milvus 向量数据库依赖于 Knowhere 库,且两部分有一部分编译内容交叉,之前的编译会将 Milvus 向量数据库中编译好的内容链接到 Knowhere 需要的文件里,在给 Knowhere **独立编译的功能后,两者之间的编译会出现重复编译的过程,也即 Milvus 向量数据库已经编译好的内容,Knowhere 会再次编译一遍,这种情况和我们优化编译流程的初衷背离。通过 if(NOT TARGET) 保证了一部分库在系统能够找到情况下不再重复进行编译,但因为作用域的问题,一些库可能并不能在 index/thirdparty 文件夹下找到(之前编译集中在 index/cmake 文件夹下进行),所以还需要进一步对一些库文件的 property 进行**。
set_target_properties( faiss PROPERTIES IMPORTED_GLOBAL TRUE IMPORTED_LOCATION "${FAISS_STATIC_LIB}" INTERFACE_INCLUDE_DIRECTORIES "${FAISS_INCLUDE_DIR}" )
#3 明确 Knowhere 和 Milvus 交叉编译内容
这个问题主要出现在 Faiss 库的编译上,Faiss 库依赖于 OpenBLAS 库进行编译。之前 Knowhere 第三方库的编译集中在一个文件下进行,尽管文件冗长,难以理解和维护,但所有需要编译的库都处于同一作用域当中,通过给 External_project ** dependency **就可以解决依赖问题。但在修改编译代码之后,Faiss 和 OpenBLAS 的编译被分配到了各自的文件夹下由父目录 thirdparty 下的 CMakeLists 进行调用,两个文件夹平行,不再能通过 add_dependency **添加依赖。
最后是通过将 OpenBLAS 的编译保留在 cmake 文件夹下,而 Faiss 的编译修改到thirdparty 目录下进行解决的,这样保证了 OpenBLAS 和 Faiss 的编译仍位于同一作用域,可以为两边的库添加依赖。
第三方库的编译依赖关系定义如下:
if(NOT OpenBLAS_FOUND) message(STATUS "OpenBLAS FOUNDED") ExternalProject_Add_StepDependencies(faiss_ep configure openblas_ep) endif()
验证优化后的编译效果
#1 Knowhere 的独立编译
Figure5 Knowhere 独立编译成功
#2 Milvus 下的编译
Figure6 Milvus 编译成功
对比修改 index 下内容前后,无 target 重复编译情况产生
项目未来规划
升级 CMake 版本,通过下载路径可配置等**加速编译流程优化编译选项并形成文档优化编译代码细节
致谢
在此要对 Goose 老师对我的指导进行致谢,在项目进行的过程中 Goose 老师耐心细致地帮我解决了很多很多问题。我自己并不是很熟悉 CMake 和编译,而且国内这方面的资料又比较少,一开始在 GitHub 上找了一个 CMake 的教程,也只是简单了解了一些常见用法,实际运用到项目中的时候是有很多不足的,这里 Goose 真的帮了很大忙,每次回复都特别及时,而且往往能一针见血找到问题出在哪里。
通过这次项目我学到了很多 CMake 相关的知识,对编译也有了很深入的了解,使我**了很大的成长和进步,也希望大家能多多关注 Milvus 社区,相信一定能有所收获。
转载自:https://mp.weixin.qq.com/s/DV1XtRpJz4i8Zd6G3pbnEA