- 人工智能
- 机器学习
- 深度学习
【免费下载链接】flashlight
A C++ standalone library for machine learning
Flashlight 是 Facebook AI Research(FAIR)与 Torch、TensorFlow、Eigen、Deep Speech 等项目创造者共同开发的一款完全用 C++ 编写、追求极致灵活与性能的机器学习库。本文以仓库根目录 README.md 为骨架,结合仓库源码带你完整掌握它的设计理念、fl / pkg / app三层架构、基于Sequential与Variable的快速编程方式,以及 vcpkg / 源码两种构建安装路径,最终能独立用它搭建自己的训练工程。
一、项目定位与核心特性
Flashlight 的定位是快速、灵活的机器学习库,其核心特性在 README.md 中总结为四点:
- 完全内部可修改性(Total internal modifiability):连张量计算的内部 API都是开放可定制的,研究者可以在库、编译器、硬件三个层面接入自己的计算栈;
- 小体积(Small footprint):核心部分控制在 10 MB 以下、约 2 万行 C++ 代码;
- 高性能默认(High-performance defaults):通过 ArrayFire 张量库实现基于现代 C++ 的即时内核编译(JIT);
- 强调效率与规模(Efficiency and scale):面向大规模分布式训练场景设计。
从根 CMakeLists.txt可以看到,当前仓库版本为0.4.0,要求C++17 标准(CMAKE_CXX_STANDARD 17),CUDA 部分出于兼容老版本 nvcc 的考虑仍保持C++14标准。项目采用 MIT 许可(见 LICENSE)。
在单一仓库内,Flashlight 为多个研究领域提供了开箱即用的应用(App),这一点充分体现了它"少约束、快迭代"的研究框架定位:
| 应用 | 说明 | 仓库位置 |
|---|---|---|
| 自动语音识别(ASR) | 前身是 wav2letter与教程 | flashlight/app/asr |
| 图像分类(Image classification) | ImageNet 级别的 ResNet / Transformer 示例 | flashlight/app/imgclass |
| 目标检测(Object detection) | 含 DETR、ResNet50 Backbone 等实现 | flashlight/app/objdet |
| 语言建模(Language modeling) | 含 Transformer 系列模型与训练器 | flashlight/app/lm |
二、仓库布局:三层架构fl / pkg / app
README 将 Flashlight 拆解为几大组成部分。需要说明的是:README 中提到的flashlight/lib(独立内核与音频处理工具)在当前仓库中已被整合进其他组件,当前仓库实际包含以下三大部分:
flashlight/fl:核心张量接口与神经网络库,默认基于 ArrayFire 张量库。它进一步细分为autograd(自动微分与Variable)、nn(神经网络模块)、optim(优化器)、dataset(数据集抽象)、distributed(分布式)、meter(评估指标)、tensor(张量框架)、runtime(设备/流管理)等子模块。统一头文件 flashlight.h 一次引入全部核心能力;flashlight/pkg:基于核心构建的领域包,包括 speech(语音)、vision(视觉)、text(文本)、runtime(训练通用工具)等。从 pkg/CMakeLists.txt 可以看到每个包都由register_package()注册,并可被 app 依赖;flashlight/app:核心库在多个机器学习领域的应用层,即编译成可执行二进制的训练/推理程序。从 app/CMakeLists.txt 可看到 asr、imgclass、objdet、lm、benchmark 均由register_app()机制按需注册构建。
这种"核心 → 领域包 → 应用"的分层让研究者既能直接用fl核心做底层实验,也能复用pkg的领域能力,还能直接运行或改造app的完整训练程序。
2.1 可插拔的张量后端:fl::Tensor框架
README 强调的"完全内部可修改性"在 flashlight/fl/tensor/README.md 中有完整定义。fl::Tensor是一个不预设立场(unopinionated)的张量前端,为在库、编译器、硬件层面集成自定义计算栈提供最小可行接口:
- 小 API 面:只需实现几十个算子即可接入新后端;
- 用户自定义内部实现:在标准高层 API 之下自由实现,不强制指定 IR;
- 计算模型灵活:JIT、即时求值(eager)等不同计算模型均可接入。
接入一个新后端只需继承两个接口:TensorAdapterBase(定义张量成员操作,见 TensorAdapter.h)与TensorBackend(定义全局张量操作,见 TensorBackend.h)。后端实现统一放在tensor/backend/[backend name]目录下——当前仓库内置了 af(ArrayFire)、jit、onednn、stub 四种后端。后端开关在 tensor/CMakeLists.txt 中通过FL_USE_ARRAYFIRE、FL_USE_JIT、FL_USE_TENSOR_STUB、FL_USE_ONEDNN四个选项控制,且至少必须启用一个后端,否则构建会直接报错。
三、快速上手:用Sequential搭一个卷积网络
README 的 Quickstart 部分展示了 Flashlight 最典型的编程范式:用Sequential容器串联各个Module,构建一个简单卷积网络(代码可直接复制运行):
#include <flashlight/fl/flashlight.h> Sequential model; model.add(View(fl::Shape({IM_DIM, IM_DIM, 1, -1}))); model.add(Conv2D( 1 /* input channels */, 32 /* output channels */, 5 /* kernel width */, 5 /* kernel height */, 1 /* stride x */, 1 /* stride y */, PaddingMode::SAME; /* padding mode */, PaddingMode::SAME; /* padding mode */)); model.add(ReLU()); model.add(Pool2D( 2 /* kernel width */, 2 /* kernel height */, 2 /* stride x */, 2 /* stride y */)); model.add(Conv2D(32, 64, 5, 5, 1, 1, PaddingMode::SAME, PaddingMode::SAME)); model.add(ReLU()); model.add(Pool2D(2, 2, 2, 2)); model.add(View(fl::Shape({7 * 7 * 64, -1}))); model.add(Linear(7 * 7 * 64, 1024)); model.add(ReLU()); model.add(Dropout(0.5)); model.add(Linear(1024, 10)); model.add(LogSoftmax());这里用到的关键组件都来自 flashlight/fl/nn:
Sequential:在 Container.h 中定义为"按顺序调用每个Module的forward,并把结果喂给下一个模块"的容器,内部持有std::vector<ModulePtr> modules_,可通过modules()、params()检查内部状态,prettyString()生成结构字符串;Conv2D/Linear/Dropout/ReLU/Pool2D/LogSoftmax:标准神经网络模块,其中Linear在 Linear.h 中封装了nIn_、nOut_、bias_参数;View:按给定Shape重塑张量,-1表示自动推断该维度。
前向与反向计算同样直白:
auto output = model.forward(input); auto loss = categoricalCrossEntropy(output, target); loss.backward();3.1 从源码看完整训练循环:MNIST 示例
README 指向的 MNIST 示例(flashlight/fl/examples/Mnist.cpp)给出了从数据加载到训练、验证、测试的完整闭环,是理解 Flashlight 训练范式的绝佳模板:
- 数据准备:用
TensorDataset+BatchDataset包装训练/验证集,BatchDataset负责按batch_size切批; - 模型构建:与上文 Quickstart 几乎一致的卷积网络(
View → Conv2D → ReLU → Pool2D交替,最后Linear → LogSoftmax); - 优化器:
SGDOptimizer opt(model.params(), learning_rate),训练超参为learning_rate = 1e-2、epochs = 10、batch_size = 64; - 训练循环:每个 batch 依次执行
loss.backward()→opt.step()→opt.zeroGrad();输入输出张量通过noGrad(...)包装避免梯度追踪; - 评估:
AverageValueMeter记录损失,FrameErrorMeter记录分类错误率,测试时先model.eval()再model.train()切换模式。
该示例最终输出接近Test Loss: 0.0373 Test Error (%): 1.1。此外,示例构建细节可参考 flashlight/fl/examples/README.md:安装后示例源码会被放置到<prefix>/share/flashlight/examples,也可作为独立项目在源码外构建。
四、自动微分:Variable与 tape-based autograd
Flashlight 的自动微分基于Variable(Variable.h)——一个tape(记录带)式的抽象,包装底层 Flashlight 张量并支持标准的反向传播。README 给出的 Autograd 示例:
auto A = Variable(fl::rand({1000, 1000}), true /* calcGrad */); auto B = 2.0 * A; auto C = 1.0 + B; auto D = log(C); D.backward(); // populates A.grad() along with gradients for B, C, and D.D.backward()会沿着计算图反向传播,为A填充A.grad(),同时计算出B、C、D各自的梯度。从源码注释可以明确其原理:Variable包装底层张量(当前默认是 ArrayFire 数组),当对输入Variable施加运算函数时,输出Variable会记录它的输入以及一个梯度函数(GradFunc),用于从输出向每个输入传播梯度;Variable与运算函数共同构成一个DAG(有向无环图)计算图,反向传播即按拓扑序从输出节点遍历这张图。
几个关键实现细节(见 Variable.h):
Variable内部以shared_ptr持有底层张量和梯度,因此拷贝构造是浅拷贝,共享同一份底层数据;- 构造时第二个参数
calcGrad决定是否需要对当前变量计算梯度; - 梯度回传使用链式法则(chain rule)沿 DAG 遍历。
对于卷积、池化、批归一化、RNN 等常见算子,Flashlight 还通过AutogradExtension提供自动微分感知的实现,其接口定义见 AutogradOps.h,并可按后端通过FL_REGISTER_TENSOR_EXTENSION(...)宏注册扩展(详见 tensor/README.md)。
五、构建与安装 Flashlight
README 给出了完整的构建矩阵:安装方式有 vcpkg 与源码两种,使用方式分为"作为已安装库链接到自己的项目"和"源码内开发(in-source development)"两种。在动手前,先确认环境满足要求。
5.1 环境要求(Requirements)
编译 Flashlight 至少需要:
- 一个对C++17支持良好的编译器(如 gcc/g++ >= 7);
- CMake3.10 或更高版本,以及
make; - 基于Linux的操作系统。
如需从源码构建,完整依赖清单见下文 5.4 节。Python 绑定的构建/安装说明另见 bindings/python/README.md(注意:Python 绑定组件已迁出到外部库,详见第七节)。
5.2 方式一:用 vcpkg 安装(推荐)
Flashlight 可以最方便地通过 vcpkg(C++ 包管理器)构建安装,CPU 与 CUDA 两种后端均受支持。无论哪种后端,都需要先安装 Intel MKL;CUDA 后端还需安装CUDA >= 9.2、cuDNN与NCCL。之后安装 vcpkg 并执行:
./vcpkg/vcpkg install flashlight-cuda # CUDA backend, OR ./vcpkg/vcpkg install flashlight-cpu # CPU backend若要安装 Flashlight 应用(App),用./vcpkg search flashlight-cuda或./vcpkg search flashlight-cpu查看可选特性(feature)。例如./vcpkg install flashlight-cuda[asr]会安装带 CUDA 后端的 ASR 应用。当前支持的 feature 清单如下:
flashlight-{cuda/cpu}[lib] # Flashlight libraries flashlight-{cuda/cpu}[nn] # Flashlight neural net library flashlight-{cuda/cpu}[asr] # Flashlight speech recognition app flashlight-{cuda/cpu}[lm] # Flashlight language modeling app flashlight-{cuda/cpu}[imgclass] # Flashlight image classification app所选 feature 对应的 app 二进制 也会被构建,并安装到 vcpkg 安装树的tools目录。
5.3 方式二:从源码构建
用 vcpkg 安装依赖后从源码构建
先按后端用 vcpkg 安装依赖。CUDA 后端依赖(按所需 feature 选择):
./vcpkg install \ cuda intel-mkl fftw3 cub kenlm \ # if building flashlight libraries arrayfire[cuda] cudnn nccl openmpi cereal stb \ # if building the flashlight neural net library gflags glog \ # if building any flashlight apps libsndfile \ # if building the flashlight asr app gtest # optional, if building testsCPU 后端依赖:
./vcpkg install \ intel-mkl fftw3 kenlm \ # for flashlight libraries arrayfire[cpu] gloo[mpi] openmpi onednn cereal stb \ # for the flashlight neural net library gflags glog \ # for the flashlight runtime pkg (any flashlight apps using it) libsndfile \ # for the flashlight speech pkg gtest # optional, for tests依赖就绪后克隆仓库并利用 vcpkg 的 CMake toolchain 构建:
git clone https://github.com/flashlight/flashlight.git && cd flashlight mkdir -p build && cd build cmake .. \ -DCMAKE_BUILD_TYPE=Release \ -DFL_BUILD_ARRAYFIRE=ON \ -DCMAKE_TOOLCHAIN_FILE=[path to your vcpkg clone]/scripts/buildsystems/vcpkg.cmake make -j$(nproc) make install -j$(nproc) # only if you want to install Flashlight for external use直接安装系统依赖后从源码构建
在依赖全部安装完毕后,克隆并构建:
git clone https://github.com/flashlight/flashlight.git && cd flashlight mkdir -p build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release -DFL_BUILD_ARRAYFIRE=ON [...build options] make -j$(nproc) make install部分依赖(表中带*标记)若在本机找不到会被自动下载并从源码构建,这一行为由FL_BUILD_STANDALONE控制,设为OFF可禁用。若 CMake 找不到 Intel MKL,可设置环境变量export MKLROOT=/opt/intel/oneapi/mkl/latest(多数 Linux 发行版为/opt/intel/mkl)辅助定位。
其他实用参数:
- 自定义安装目录:用 CMake 的
CMAKE_INSTALL_PREFIX; - 构建共享库:用 CMake 的
BUILD_SHARED_LIBS; - 依赖定位:Flashlight 使用现代 CMake 的
IMPORTEDtargets,若某依赖未被找到,可传-D<package>_DIR指向该依赖的Config.cmake所在目录。
macOS 最小化构建
在 macOS 上可用 Homebrew 安装 ArrayFire 后做最小化构建:
brew install arrayfire cmake .. \ -DFL_ARRAYFIRE_USE_OPENCL=ON \ -DFL_USE_ONEDNN=OFF \ -DFL_BUILD_TESTS=OFF \ -DFL_BUILD_EXAMPLES=OFF \ -DFL_BUILD_SCRIPTS=OFF \ -DFL_BUILD_DISTRIBUTED=OFF make -j$(nproc)5.4 依赖对照表
下表完整列出各组件在不同后端下的依赖(*:未找到时自动下载构建,由FL_BUILD_STANDALONE控制;^:仅在开启分布式训练FL_BUILD_DISTRIBUTED时需要,所有 App 都需要分布式训练;†:可通过 vcpkg 安装):
| 组件 | 后端 | 依赖 |
|---|---|---|
| libraries | CUDA | CUDA >= 9.2、CUB*†(CUDA < 11 时) |
| libraries | CPU | 一个 BLAS 库(Intel MKL >= 2018、OpenBLAS† 等) |
| core | 任意 | ArrayFire >= 3.7.3†、MPI 库^(OpenMPI† 等)、cereal*† >= 1.3.0、stb*† |
| core | CUDA | CUDA >= 9.2、NCCL^、cuDNN |
| core | CPU | oneDNN† >= 2.5.2、gloo(带 MPI)*^† |
| app: all | 任意 | Google Glog†、Gflags† |
| app: asr | 任意 | libsndfile*† >= 10.0.28、BLAS 库(Intel MKL >= 2018、OpenBLAS† 等)、flashlight/text* |
| app: imgclass | 任意 | - |
| app: lm | 任意 | flashlight/text* |
| tests | 任意 | Google Test(gtest,含 gmock)*† >= 1.10.0 |
5.5 构建选项(Build Options)
CMake 构建可接受的完整选项如下(命令行运行时用-D前缀,例如-DFL_BUILD_TESTS=OFF):
| 名称 | 选项 | 默认值 | 说明 |
|---|---|---|---|
| FL_BUILD_ARRAYFIRE | ON, OFF | ON | 使用 ArrayFire 后端构建 Flashlight |
| FL_BUILD_STANDALONE | ON, OFF | ON | 找不到某些依赖时下载/构建它们 |
| FL_BUILD_LIBRARIES | ON, OFF | ON | 构建 Flashlight 库 |
| FL_BUILD_NN | ON, OFF | ON | 构建 Flashlight 神经网络库 |
| FL_BUILD_DISTRIBUTED | ON, OFF | ON | 开启分布式训练支持;所有 App 都需要 |
| FL_BUILD_CONTRIB | ON, OFF | ON | 构建可能发生破坏性变更的 contrib API |
| FL_BUILD_APPS | ON, OFF | ON | 构建应用程序(见下) |
| FL_BUILD_APP_ASR | ON, OFF | ON | 构建自动语音识别应用 |
| FL_BUILD_APP_IMGCLASS | ON, OFF | ON | 构建图像分类应用 |
| FL_BUILD_APP_LM | ON, OFF | ON | 构建语言建模应用 |
| FL_BUILD_APP_ASR_TOOLS | ON, OFF | ON | 构建 ASR 应用工具(app/asr/CMakeLists.txt) |
| FL_BUILD_TESTS | ON, OFF | ON | 构建测试 |
| FL_BUILD_EXAMPLES | ON, OFF | ON | 构建示例 |
| FL_BUILD_EXPERIMENTAL | ON, OFF | OFF | 构建实验性组件 |
| CMAKE_BUILD_TYPE | 见 CMake 文档 | Debug | 构建类型 |
| CMAKE_INSTALL_PREFIX | [目录] | 见 CMake 文档 | 安装前缀目录 |
构建子集提示:README 中FL_BUILD_APPS等选项的"ON"默认值对应完整构建;实际仓库中 App 的注册是条件式的——app/CMakeLists.txt 通过fl_dependent_option生成FL_BUILD_APP_*选项,其默认值由依赖条件推导(如 objdet 默认关闭),因此按需关闭不需要的 App 即可显著缩短构建时间。同理,FL_BUILD_PKG_*(runtime/vision/text/speech)在 pkg/CMakeLists.txt 中注册,FL_USE_*(ARRAYFIRE/JIT/TENSOR_STUB/ONEDNN/CUDNN/NCCL/GLOO)控制张量与计算后端,见 tensor/CMakeLists.txt 与 distributed/CMakeLists.txt。
六、用 Flashlight 构建你自己的项目
Flashlight 最适合通过 CMake 链接。安装后会导出以下 CMake targets:
flashlight::flashlight— 包含 Flashlight 库以及核心自动微分与神经网络库;flashlight::fl_pkg_runtime— 核心 + 训练通用工具(日志 / flags / 分布式工具,实现在 pkg/runtime/Runtime.h);flashlight::fl_pkg_vision— 核心 + 视觉管线通用工具;flashlight::fl_pkg_text— 核心 + 文本数据处理通用工具;flashlight::fl_pkg_speech— 核心 + 语音数据处理通用工具;flashlight::fl_pkg_halide— 核心 + 与 Halide 交互的扩展。
假设有一个简单的project.cpp:
#include <iostream> #include <flashlight/fl/flashlight.h> int main() { fl::init(); fl::Variable v(fl::full({1}, 1.), true); auto result = v + 10; std::cout << "Tensor value is " << result.tensor() << std::endl; // 11.000 return 0; }对应的 CMake 配置如下:
cmake_minimum_required(VERSION 3.10) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) add_executable(myProject project.cpp) find_package(flashlight CONFIG REQUIRED) target_link_libraries(myProject PRIVATE flashlight::flashlight)注意:
project.cpp中先调用fl::init()再创建Variable,这是 Flashlight 初始化运行时的标准入口;Variable构造函数的第二个参数true表示需要梯度。
6.1 基于 vcpkg 安装的集成
如果 Flashlight 由 vcpkg 安装,用 vcpkg 的 CMake toolchain 构建myProject:
cd project && mkdir build && cd build cmake .. \ -DCMAKE_TOOLCHAIN_FILE=[path to vcpkg clone]/scripts/buildsystems/vcpkg.cmake \ -DCMAKE_BUILD_TYPE=Release make -j$(nproc)6.2 基于源码安装的集成
如果是源码安装,CMake 会自动找到 Flashlight:
cd project && mkdir build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release make -j$(nproc)若 Flashlight 安装在自定义前缀(通过CMAKE_INSTALL_PREFIX),需要传-Dflashlight_DIR=[install prefix]/share/flashlight/cmake帮助 CMake 定位。
6.3 使用 Docker
Flashlight 及其依赖也可以用仓库提供的 Dockerfile 构建运行,构建好的镜像对应 CUDA 与 CPU 后端均有发布,具体用法可参考仓库.docker目录下的文档。
七、Python 绑定说明
如需在 Python 中使用 Flashlight 生态,注意 bindings/python/README.md 的说明:Python 绑定组件已从本仓库迁出到两个外部库:
- Flashlight Text:文本处理工具,包括 beam search 解码器、词典抽象与分词器;
- Flashlight Sequence:序列损失函数的 CPU/GPU 实现,包括 CTC(Connectionist Temporal Classification)与 ASG(Auto Segmentation)。
本仓库不再包含其他 Python 绑定组件,相关问题与贡献请到对应仓库提交。
八、参与贡献、引用与许可证
Flashlight 处于非常活跃的开发中,贡献指南见 CONTRIBUTING.md。引用 Flashlight 时,可使用其论文(arXiv:2201.12465)对应的 BibTeX:
@misc{kahn2022flashlight, title={Flashlight: Enabling Innovation in Tools for Machine Learning}, author={Jacob Kahn and Vineel Pratap and Tatiana Likhomanenko and Qiantong Xu and Awni Hannun and Jeff Cai and Paden Tomasello and Ann Lee and Edouard Grave and Gilad Avidov and Benoit Steiner and Vitaliy Liptchinsky and Gabriel Synnaeve and Ronan Collobert}, year={2022}, eprint={2201.12465}, archivePrefix={arXiv}, primaryClass={cs.LG} }项目部分代码派生自 arrayfire-ml,并以 MIT 许可证开源(见 LICENSE)。
结语:从研究框架到你的第一个 Flashlight 工程
本文沿着仓库 README.md 的主线,完成了从"为什么需要 Flashlight"到"如何用 Flashlight 干活"的完整闭环:先理解其fl / pkg / app三层架构与可插拔张量后端的设计哲学,再通过Sequential与Variable掌握核心编程范式,随后按 vcpkg 或源码两种路径完成构建安装,最后用导出的 CMake targets 把 Flashlight 接入自己的项目。接下来你可以直接阅读 flashlight/fl/examples/Mnist.cpp 的完整训练循环,或进入 flashlight/app/asr 的教程,把这套框架真正跑起来。
- 人工智能
- 机器学习
- 深度学习
【免费下载链接】flashlight
A C++ standalone library for machine learning
相关推荐
如何训练自定义Zero-1-to-3模型:从零开始的完整教程
如何训练自定义Zero 1 to 3模型:从零开始的完整教程 想要从单张图片生成3D对象吗?Zero 1 to 3模型让这成为可能!这个强大的AI模型能够将任意
mlpack 4 快速上手:header-only C++ 机器学习库的安装、编译与实战指南
mlpack 4 快速上手:header only C++ 机器学习库的安装、编译与实战指南 mlpack 是一个以 C++ 为核心、以“快速、轻量、heade
人工智能机器学习深度学习Flashlight机器学习库:面向未来的C++深度学习框架终极指南
Flashlight机器学习库:面向未来的C++深度学习框架终极指南 Flashlight是一个完全用C++编写的高速、灵活机器学习库,由Facebook AI
人工智能机器学习深度学习
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考