Morpheus 贡献指南
对 Morpheus 的贡献分为以下三个类别。
要报告错误、请求新功能或报告文档问题,请提交 issue,详细描述问题或新功能。Morpheus 团队会评估和分类 issue,并将其安排到发布版本中。如果您认为该 issue 需要优先关注,请在 issue 中评论以通知团队。
要提出和实施新功能,请提交新功能请求 issue。描述预期功能,并与团队和社区讨论设计和实施方案。一旦团队同意该计划可行,请继续实施,使用下方的 代码贡献 指南。
要为现有的未解决 issue 实施功能或错误修复,请遵循下方的 代码贡献 指南。如果您需要关于特定 issue 的更多背景信息,请在评论中提问。
作为该项目的贡献者和维护者,您需要遵守 Morpheus 的行为准则。更多信息请见:贡献者行为准则。
您的第一个 issue
查找要处理的 issue。最好的方法是搜索带有 good first issue 标签的 issue。
在 issue 中评论,声明您将处理它。
编写代码!确保更新单元测试!确保 正确设置许可证头。
完成后,创建您的拉取请求。
等待其他开发者审查您的代码,并根据需要更新代码。
一旦审查并批准,Morpheus 开发者将合并您的拉取请求。
请记住,如果您对任何事情不确定,请随时在 issue 中评论并请求澄清!
经验丰富的开发者
一旦您熟悉了代码并感到更舒适,您可以查看我们的 项目看板 中为下个版本优先处理的 issue。
专家提示: 始终查看 issue 编号最高的发布看板,以了解要处理的 issue。这也是 Morpheus 开发者集中精力的地方。
查看未分配的 issue,并找到您有信心贡献的 issue。从上面的步骤 2 开始,在 issue 中评论以告知其他人您正在处理它。如果您有任何与 issue 实施相关的问题,请在 issue 中而不是 PR 中提出。
以下说明适用于刚开始使用 Morpheus 仓库的开发者。Morpheus 开发环境是灵活的(Docker、Conda 和裸机工作流),但有大量依赖项,可能难以设置。这些说明概述了在 Docker 容器内或使用 Conda 的主机上设置开发环境的步骤。
以下所有说明均假定已定义给定变量
MORPHEUS_ROOT
:Morpheus 仓库已检出到此变量指定的位置。任何非绝对路径都相对于MORPHEUS_ROOT
。
克隆仓库并从 Git LFS 拉取大型文件数据
export MORPHEUS_ROOT=$(pwd)/morpheus
git clone https://github.com/nv-morpheus/Morpheus.git $MORPHEUS_ROOT
cd $MORPHEUS_ROOT
确保所有子模块都已检出
git submodule update --init --recursive
此仓库中的大型模型和数据文件使用 Git Large File Storage (LFS) 存储。运行 Morpheus 预训练模型的训练/验证脚本和示例管道将需要这些文件。
默认情况下,克隆 Morpheus 仓库时,仅包含严格运行 Morpheus 所需的 LFS 存储文件。可以使用 scripts/fetch_data.py
脚本下载其他数据集。有关详细信息,请参阅 Git LFS 部分,该部分位于 getting_started.md 指南中。
在 Docker 容器中构建
此工作流程利用 Docker 容器来设置大多数依赖项,从而确保一致的环境。
先决条件
确保满足 requirements 中 getting_started.md 的所有要求。
构建开发容器
./docker/build_container_dev.sh
容器标签将默认为
morpheus:YYMMDD
,其中YYMMDD
分别是当前年份、月份和日期的 2 位数字。可以通过设置DOCKER_IMAGE_TAG
来覆盖标签。例如,DOCKER_IMAGE_TAG=my_tag ./docker/build_container_dev.sh
将构建容器
morpheus:my_tag
。要构建安装了 CPython 调试版本的容器,请按如下方式更新 Docker 目标
DOCKER_TARGET=development_pydbg ./docker/build_container_dev.sh
注意:调试 Python 代码时,您只需将
ci/conda/recipes/python-dbg/source
添加到调试器的源路径即可。创建后,您将能够从 GDB 中内省 Python 对象。例如,如果我们要在生成器设置调用中中断并检查其
PyFrame_Object
f
,它可能类似于
#4 0x000056498ce685f4 in gen_send_ex (gen=0x7f3ecc07ad40, arg=<optimized out>, exc=<optimized out>, closing=<optimized out>) at Objects/genobject.c:222 (gdb) pyo f object address : 0x7f3eb3888750 object refcount : 1 object type : 0x56498cf99c00 object type name: frame object repr : <frame at 0x7f3eb3888750, file '/workspace/morpheus/pipeline/pipeline.py', line 902, code join
注意:现在运行容器时,Conda 应将您的 Python 版本列为
pyxxx_dbg_morpheus
。
(morpheus) user@host:/workspace# conda list | grep python python 3.8.13 py3.8.13_dbg_morpheus local
注意:这不会构建任何 Morpheus 或 MRC 代码,并且会将代码构建推迟到可以将整个仓库挂载到正在运行的容器中。这允许在开发期间进行更快的增量构建。
运行开发容器
./docker/run_container_dev.sh
容器标签遵循与
build_container_dev.sh
相同的规则,默认设置为当前YYMMDD
。使用DOCKER_IMAGE_TAG
指定所需的标签。例如,DOCKER_IMAGE_TAG=my_tag ./docker/run_container_dev.sh
这会自动将当前工作目录挂载到
/workspace
。某些验证测试需要在 Morpheus 容器内启动 Morpheus 模型 Docker 容器。要启用此功能,您需要授予 Morpheus 容器访问主机操作系统的 Docker 套接字文件的权限,方法是
DOCKER_EXTRA_ARGS="-v /var/run/docker.sock:/var/run/docker.sock" ./docker/run_container_dev.sh
然后在容器启动后,您需要安装一些额外的软件包才能启用启动 Docker 容器的功能
./external/utilities/docker/install_docker.sh
编译 Morpheus
./scripts/compile.sh
此脚本将使用默认选项运行 CMake 配置、CMake 构建并将 Morpheus 安装到环境中。
morpheus run pipeline-nlp ...
此时,Morpheus 可以完全使用。对 Python 代码的任何更改都不需要重建。对 C++ 代码的更改将需要调用
./scripts/compile.sh
。
在 Conda 环境中构建
如果在主机上首选 Conda 环境而不是 Docker,则相对容易安装必要的依赖项(实际上,Docker 工作流程在容器内创建 Conda 环境)。
Conda 环境 YAML 文件
Morpheus 提供了多个 Conda 环境文件来支持不同的工作流程。Morpheus 利用 rapids-dependency-file-generator 来管理这些多个环境文件。Morpheus 的所有 Conda 和 pip 依赖项以及不同的环境都在 dependencies.yaml
文件中定义。
以下是可用的 Conda 环境文件,所有文件都位于 conda/environments
目录中,命名约定如下:<environment>_<cuda_version>_arch-<architecture>.yaml
。
环境 |
文件 |
描述 |
---|---|---|
all |
all_cuda-125_arch-x86_64.yaml |
构建、运行和测试 Morpheus 以及所有示例所需的所有依赖项。这是 dev 、runtime 和 examples 环境的超集。 |
dev |
dev_cuda-125_arch-x86_64.yaml |
构建、运行和测试 Morpheus 所需的依赖项。这是 runtime 环境的超集。 |
examples |
examples_cuda-125_arch-x86_64.yaml |
运行所有示例所需的依赖项。这是 runtime 环境的超集。 |
model-utils |
model-utils_cuda-125_arch-x86_64.yaml |
独立于 Morpheus 训练模型所需的依赖项。 |
runtime |
runtime_cuda-125_arch-x86_64.yaml |
严格运行 Morpheus 所需的最少依赖项集。 |
更新 Morpheus 依赖项
可以在 dependencies.yaml
文件中更改 Morpheus 依赖项,然后运行 rapids-dependency-file-generator
以更新 conda/environments
目录中的各个环境文件。
将 rapids-dependency-file-generator
安装到基本 Conda 环境中
conda run -n base --live-stream pip install rapids-dependency-file-generator
然后生成更新各个环境文件运行
conda run -n base --live-stream rapids-dependency-file-generator
准备就绪后,将对 dependencies.yaml
文件和更新后的环境文件的更改都提交到仓库中。
先决条件
Volta 架构 GPU 或更好
conda
如果未安装
conda
,我们建议使用 MiniForge 安装指南。这将安装conda
并将频道默认设置为使用conda-forge
。
设置环境变量并克隆仓库
export MORPHEUS_ROOT=$(pwd)/morpheus git clone https://github.com/nv-morpheus/Morpheus.git $MORPHEUS_ROOT cd $MORPHEUS_ROOT
确保所有子模块都已检出
git submodule update --init --recursive
使用
dev
或all
环境文件创建 Morpheus Conda 环境。有关更多信息,请参阅 Conda 环境 YAML 文件 部分。conda env create --solver=libmamba -n morpheus --file conda/environments/dev_cuda-125_arch-x86_64.yaml
或
conda env create --solver=libmamba -n morpheus --file conda/environments/all_cuda-125_arch-x86_64.yaml
这将创建一个名为
morpheus
的新环境。使用以下命令激活环境conda activate morpheus
构建 Morpheus
./scripts/compile.sh
此脚本将构建 Morpheus 并将其安装到 Conda 环境中。
测试构建(注意:某些测试将被跳过)某些测试将依赖于外部数据集。
MORPHEUS_ROOT=${PWD} git lfs install git lfs update ./scripts/fetch_data.py fetch all
此脚本将获取所需的数据集。然后运行
pytest
可选:运行完整的端到端测试
我们的端到端测试需要 camouflage 测试框架。使用以下命令安装 camouflage
npm install -g camouflage-server@0.15
运行端到端(又称慢速)测试
pytest --run_slow
可选:运行 Kafka 和 Milvus 测试
下载 Kafka
python ./ci/scripts/download_kafka.py
运行所有测试(这将跳过需要未安装的可选依赖项的测试)
pytest --run_slow --run_kafka --run_milvus
运行包括需要可选依赖项的所有测试
pytest --fail_missing --run_slow --run_kafka --run_milvus
运行 Morpheus
morpheus run pipeline-nlp ...
此时,Morpheus 可以完全使用。对 Python 代码的任何更改都不需要重建。对 C++ 代码的更改将需要调用
./scripts/compile.sh
。每个虚拟环境只需要安装一次 Morpheus。
构建 Morpheus 模型容器
从 Morpheus 仓库的根目录运行以下命令
models/docker/build_container.sh
快速启动 Kafka 集群
启动完整的生产 Kafka 集群不在此项目范围之内;但是,如果需要快速集群进行测试或开发,则可以使用 Docker Compose 快速启动一个集群。以下命令概述了该过程。有关更深入的信息,请参阅 本 指南
如果尚未安装,请安装
docker-compose-plugin
apt-get update apt-get install docker-compose-plugin
从 Morpheus 仓库根目录克隆
kafka-docker
仓库git clone https://github.com/wurstmeister/kafka-docker.git
将目录更改为
kafka-docker
cd kafka-docker
导出 Docker
bridge
网络的 IP 地址export KAFKA_ADVERTISED_HOST_NAME=$(docker network inspect bridge | jq -r '.[0].IPAM.Config[0].Gateway')
更新
kafka-docker/docker-compose.yml
,执行两项更改更新
ports
条目为ports: - "0.0.0.0::9092"
这将防止容器尝试映射 IPv6 端口。
更改
KAFKA_ADVERTISED_HOST_NAME
的值以匹配上一步中KAFKA_ADVERTISED_HOST_NAME
环境变量的值。例如,该行应类似于environment: KAFKA_ADVERTISED_HOST_NAME: 172.17.0.1
它应与上一步中
$KAFKA_ADVERTISED_HOST_NAME
的值匹配$ echo $KAFKA_ADVERTISED_HOST_NAME "172.17.0.1"
启动包含 3 个实例的 Kafka
docker compose up -d --scale kafka=3
在实践中,3 个实例已证明效果良好。根据需要使用任意数量的实例。请记住,每个实例占用约 1 GB 的内存。
启动 Kafka shell
要配置集群,您需要启动到具有 Kafka shell 的容器中。
您可以使用以下命令执行此操作
./start-kafka-shell.sh $KAFKA_ADVERTISED_HOST_NAME
但是,这使得将数据加载到集群中变得困难。相反,您可以手动启动 Kafka shell,方法是运行
# Change to the morpheus root to make it easier for mounting volumes cd ${MORPHEUS_ROOT} # Run the Kafka shell Docker container docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock \ -e HOST_IP=$KAFKA_ADVERTISED_HOST_NAME -e ZK=$2 \ -v $PWD:/workspace wurstmeister/kafka /bin/bash
请注意
-v $PWD:/workspace
。这将使您当前目录中的任何内容在/workspace
中可用。启动 Kafka shell 后,您可以开始配置集群。以下所有命令都需要参数
--bootstrap-server
。为了简化操作,请设置BOOTSTRAP_SERVER
和MY_TOPIC
变量export BOOTSTRAP_SERVER=$(broker-list.sh) export MY_TOPIC="your_topic_here"
创建主题
# Create the topic kafka-topics.sh --bootstrap-server ${BOOTSTRAP_SERVER} --create --topic ${MY_TOPIC} # Change the number of partitions kafka-topics.sh --bootstrap-server ${BOOTSTRAP_SERVER} --alter --topic ${MY_TOPIC} --partitions 3 # Refer to the topic info kafka-topics.sh --bootstrap-server ${BOOTSTRAP_SERVER} --describe --topic=${MY_TOPIC}
注意: 如果您正在使用
to-kafka
,请确保也创建了您的输出主题。生成输入消息
为了使 Morpheus 从 Kafka 读取数据,需要将消息发布到集群。您可以使用
kafka-console-producer.sh
脚本加载数据kafka-console-producer.sh --bootstrap-server ${BOOTSTRAP_SERVER} --topic ${MY_TOPIC} < ${FILE_TO_LOAD}
注意: 为了使其正常工作,您的输入文件必须可以从启动 Kafka shell 的当前目录访问。
您可以使用以下命令查看消息
kafka-console-consumer.sh --bootstrap-server ${BOOTSTRAP_SERVER} --topic ${MY_TOPIC}
注意: 这将消耗消息。
管道验证
为了验证所有管道是否正常工作,已在 ${MORPHEUS_ROOT}/scripts/validation
中添加了验证脚本。每个主要工作流程都有脚本:异常行为分析 (ABP)、网络钓鱼检测(Phishing)和敏感信息检测 (SID)。
要运行所有验证工作流程脚本,请使用以下命令
# Run validation scripts
./scripts/validation/val-run-all.sh
在每个工作流程结束时,将显示一个部分,其中打印运行的不同推理工作负载以及每个工作负载的验证错误百分比。例如
===ERRORS===
PyTorch :3/314 (0.96 %)
Triton(ONNX):Skipped
Triton(TRT) :Skipped
TensorRT :Skipped
Complete!
这表明只有 314 行中的 3 行与验证数据集不匹配。如果显示类似于 :/ ( %)
的错误或非常高的百分比,则表示工作流程未成功完成。
构建故障排除
由于依赖项数量众多,因此遇到构建问题是很常见的。以下是一些常见问题、提示和建议
构建缓存问题
为了避免在每次更改后为所有依赖项重建每个编译单元,构建的很大一部分被缓存。默认情况下,缓存位于
${MORPHEUS_ROOT}/.cache
。缓存包含已编译的对象文件、源代码仓库、ccache 文件、clangd 文件,甚至 cuDF 构建。可以随时删除整个缓存文件夹,并在下次构建时重新下载/重新创建
指示
git apply ...
失败的消息许多依赖项需要小的补丁才能使其工作。这些补丁必须应用一次且仅一次。如果显示此错误,请尝试从
build/_deps/<offending_package>
目录或.cache/cpm/<offending_package>
中删除有问题的软件包。如果所有其他方法都失败,请删除整个
build/
目录和.cache/
目录。
执行就地构建时的旧构建工件。
使用
MORPHEUS_PYTHON_INPLACE_BUILD=ON
构建时,编译后的库将就地部署在源代码树中,并且旧的构建工件存在于源代码树中。使用以下命令删除这些工件find ./python -name "*.so" -delete find ./examples -name "*.so" -delete
构建文档问题
中间文档构建工件可能会导致 Sphinx 错误。要删除这些工件,请运行
rm -rf build/docs/ docs/source/_modules docs/source/_lib
CI 问题
要在本地运行 CI,可以使用
ci/scripts/run_ci_local.sh
脚本。例如,要运行本地 CI 构建ci/scripts/run_ci_local.sh build
本地 CI 运行生成的构建工件可以在
.tmp/local_ci_tmp/
目录中找到。
要排除特定 CI 阶段的故障,运行以下命令可能会有所帮助
ci/scripts/run_ci_local.sh bash
这将在 CI 容器内打开一个 bash shell,其中包含 CI 运行期间通常设置的所有环境变量。从这里,您可以运行通常由
ci/scripts/github
中的 CI 脚本之一运行的命令。要运行需要 GPU 的 CI 阶段(例如:
test
),请将USE_GPU
环境变量设置为1
USE_GPU=1 ci/scripts/run_ci_local.sh bash
有关常见问题以及如何解决这些问题的更多信息,请参阅 故障排除指南。
Morpheus 在 Apache v2.0 许可下获得许可。所有新的源文件(包括 CMake 和其他构建脚本)都应包含 Apache v2.0 许可头。对现有源代码的任何编辑都应将版权的日期范围更新为当前年份。许可证头的格式为
/*
* SPDX-FileCopyrightText: Copyright (c) <year>, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
第三方代码
源代码树中包含的第三方代码(未作为外部依赖项拉入)必须与 Apache v2.0 许可证兼容,并且应保留原始许可证以及指向源代码的 URL。如果修改了此代码,则应包含 Apache v2.0 许可证,后跟代码的原始许可证和指向原始代码的 URL。
示例
/**
* SPDX-FileCopyrightText: Copyright (c) <year>, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//
// Original Source: https://github.com/org/other_project
//
// Original License:
// ...