Cleanup of the book + feature flags (#773)

---------

Co-authored-by: louisfd <louisfd94@gmail.com>
This commit is contained in:
Nathaniel Simard 2023-09-06 09:16:36 -04:00 committed by GitHub
parent 6095dd104e
commit 8b3d10c4d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 114 additions and 95 deletions

View File

@ -18,7 +18,7 @@
- [Config](./building-blocks/config.md)
- [Record](./building-blocks/record.md)
- [Dataset](./building-blocks/dataset.md)
- [Custom Training Loops](./custom-training-loop.md)
- [Custom Training Loop](./custom-training-loop.md)
- [Import ONNX Model](./import/onnx-model.md)
- [Advanced](./advanced/README.md)
- [Backend Extension](./advanced/backend-extension/README.md)

View File

@ -238,9 +238,6 @@ impl<G: GraphicsApi, F: FloatElement, I: IntElement> Backend for WgpuBackend<G,
// Create the output tensor primitive.
let output = WgpuTensor::new(lhs.context.clone(), shape_out, buffer);
let blocks_needed_in_x = f32::ceil(num_rows as f32 / workgroup_size_x as f32) as u32;
let blocks_needed_in_y = f32::ceil(num_cols as f32 / workgroup_size_y as f32) as u32;
// Compile the kernel or use the cache based on the template id.
let kernel = lhs.context.compile_dynamic(FusedMatmulAddRelu::<F>::new(
workgroup_size_x,
@ -254,6 +251,8 @@ impl<G: GraphicsApi, F: FloatElement, I: IntElement> Backend for WgpuBackend<G,
.create_buffer_with_data(bytemuck::cast_slice(&info));
// Declare the wgsl workgroup with the number of blocks in x, y and z.
let blocks_needed_in_x = f32::ceil(num_rows as f32 / workgroup_size_x as f32) as u32;
let blocks_needed_in_y = f32::ceil(num_cols as f32 / workgroup_size_y as f32) as u32;
let workgroup = WorkGroup::new(blocks_needed_in_x, blocks_needed_in_y, num_batches as u32);
// Execute lazily the kernel with the launch information and the given buffers.

View File

@ -1,15 +1,17 @@
# Backend
We have effectively written most of the necessary code for training our model. However, we have not explicitly designated the backend to be utilized at any point.
Indeed, only the `main` function remains.
We have effectively written most of the necessary code for training our model. However, we have not
explicitly designated the backend to be used at any point. Indeed, only the `main` function remains.
```rust , ignore
use burn::optim::AdamConfig;
use burn::backend::{WgpuBackend, wgpu::AutoGraphicsApi};
use burn::autodiff::ADBackendDecorator;
use guide::model::ModelConfig;
fn main() {
type MyBackend = burn_wgpu::WgpuBackend<burn_wgpu::AutoGraphicsApi, f32, i32>;
type MyAutodiffBackend = burn_autodiff::ADBackendDecorator<MyBackend>;
type MyBackend = WgpuBackend<AutoGraphicsApi, f32, i32>;
type MyAutodiffBackend = ADBackendDecorator<MyBackend>;
let device = burn_wgpu::WgpuDevice::default();
guide::training::train::<MyAutodiffBackend>(
@ -20,11 +22,17 @@ fn main() {
}
```
In this example, we use the `WgpuBackend` which is compatible with any operating system and will use the GPU. For other options, see the Burn README.
This backend type takes the graphics api, the float type and the int type as generic argument that will be used during the training. By leaving the graphics API as `burn_wgpu::AutoGraphicsApi`, it should automatically use an API available on your machine.
The autodiff backend is simply the same backend, wrapped within the `ADBackendDecorator` struct which imparts differentiability to any backend.
In this example, we use the `WgpuBackend` which is compatible with any operating system and will use
the GPU. For other options, see the Burn README. This backend type takes the graphics api, the float
type and the int type as generic arguments that will be used during the training. By leaving the
graphics API as `AutoGraphicsApi`, it should automatically use an API available on your machine. The
autodiff backend is simply the same backend, wrapped within the `ADBackendDecorator` struct which
imparts differentiability to any backend.
We call the `train` function defined earlier with a directory for artifacts, the configuration of the model (the number of digit classes is 10 and the hidden dimension is 512), the optimizer configuration which in our case will be the default Adam configuration, and the device which can be obtained from the backend.
We call the `train` function defined earlier with a directory for artifacts, the configuration of
the model (the number of digit classes is 10 and the hidden dimension is 512), the optimizer
configuration which in our case will be the default Adam configuration, and the device which can be
obtained from the backend.
When running the example, we can see the training progression through a basic CLI dashboard:

View File

@ -7,14 +7,11 @@ file, add the `burn`, `burn-wgpu`, `burn-dataset`, `burn-autodiff` and `burn-tra
```toml
[package]
edition = "2021"
name = "My first Burn model"
name = "my-first-burn-model"
version = "0.1.0"
[dependencies]
burn = "0.9"
burn-wgpu = "0.9"
burn-dataset = "0.9"
burn-autodiff = "0.9"
burn-train = "0.9"
burn = { version = "0.9.0", features=["train", "wgpu"]}
# Serialization
serde = "1"
@ -63,8 +60,8 @@ There are two major things going on in this code sample.
underlying low level implementations of tensor operations, allowing your new model to run on any
backend. Contrary to other frameworks, the backend abstraction isn't determined by a compilation
flag or a device type. This is important because you can extend the functionalities of a specific
backend (which will be covered in the more advanced sections of this book), and it allows for an
innovative autodiff system. You can also change backend during runtime, for instance to compute
backend (see [backend extension section](../advanced/backend-extension)), and it allows for an
innovative [autodiff system](../building-blocks/autodiff.md). You can also change backend during runtime, for instance to compute
training metrics on a cpu backend while using a gpu one only to train the model. In our example,
the backend in use will be determined later on.

View File

@ -160,6 +160,6 @@ set; however, we do not recommend this practice for actual usage.
Finally, the trained model is returned by the `fit` method, and the only remaining task is saving
the trained weights using the `CompactRecorder`. This recorder employs the `MessagePack` format with
`gzip` compression, `f16` for floats and `i32` for integers. Other recorders are available, offering
`gzip` compression, `f16` for floats and `i16` for integers. Other recorders are available, offering
support for various formats, such as `BinCode` and `JSON`, with or without compression. Any backend,
regardless of precision, can load recorded data of any kind.

View File

@ -6,7 +6,7 @@ well-crafted and flexible training loop, so that projects do not have to write s
the ground up. Most of the interactions with `burn-train` will be with the `LearnerBuilder` struct,
briefly presented in the previous [training section](../basic-workflow/training.md). This struct
enables you to configure the training loop, offering support for registering metrics, enabling
logging, checkpointing states, utilizing multiple devices, and so on.
logging, checkpointing states, using multiple devices, and so on.
There are still some assumptions in the current provided APIs, which may make them inappropriate for
your learning requirements. Indeed, they assume your model will learn from a training dataset and be

View File

@ -105,6 +105,18 @@ pub trait ModuleMapper<B: Backend> {
Burn comes with built-in modules that you can use to build your own modules.
### General
| Burn API | PyTorch Equivalent |
| ----------- | --------------------------------------- |
| `BatchNorm` | `nn.BatchNorm1d`, `nn.BatchNorm2d` etc. |
| `LayerNorm` | `nn.LayerNorm` |
| `Dropout` | `nn.Dropout` |
| `GELU` | `nn.GELU` |
| `Linear` | `nn.Linear` |
| `Embedding` | `nn.Embedding` |
| `Relu` | `nn.ReLU` |
### Convolutions
| Burn API | PyTorch Equivalent |
@ -114,25 +126,6 @@ Burn comes with built-in modules that you can use to build your own modules.
| `ConvTranspose1d` | `nn.ConvTranspose1d` |
| `ConvTranspose2d` | `nn.ConvTranspose2d` |
### General
| Burn API | PyTorch Equivalent |
| ----------- | --------------------------------------- |
| `BatchNorm` | `nn.BatchNorm1d`, `nn.BatchNorm2d` etc. |
| `Dropout` | `nn.Dropout` or `nn.Dropout2d` etc. |
| `GELU` | `nn.GELU` |
| `LayerNorm` | `nn.LayerNorm` |
| `Linear` | `nn.Linear` |
| `Embedding` | `nn.Embedding` |
| `Relu` | `nn.ReLU` |
### Loss
| Burn API | PyTorch Equivalent |
| ------------------ | --------------------- |
| `CrossEntropyLoss` | `nn.CrossEntropyLoss` |
| `MSELoss` | `nn.MSELoss` |
### Pooling
| Burn API | PyTorch Equivalent |
@ -160,3 +153,10 @@ Burn comes with built-in modules that you can use to build your own modules.
| `TransformerDecoder` | `nn.TransformerDecoder` |
| `TransformerEncoder` | `nn.TransformerEncoder` |
| `PositionalEncoding` | _No direct equivalent_ |
### Loss
| Burn API | PyTorch Equivalent |
| ------------------ | --------------------- |
| `CrossEntropyLoss` | `nn.CrossEntropyLoss` |
| `MSELoss` | `nn.MSELoss` |

View File

@ -168,3 +168,4 @@ Those operations are only available for `Bool` tensors.
| ---------------- | ----------------------------------- |
| `tensor.float()` | Similar to `tensor.to(torch.float)` |
| `tensor.int()` | Similar to `tensor.to(torch.long)` |
| `tensor.not()` | `tensor.logical_not()` |

View File

@ -37,8 +37,7 @@ edition = "2021"
Under dependencies, add
```toml
burn = "0.9.0"
burn-wgpu = "0.9.0"
burn = { version = "0.9.0", features = ["wgpu"] }
```
Then, to compile the dependencies, execute
@ -56,12 +55,12 @@ Now open `src/main.rs` and replace its content with
```rust
use burn::tensor::Tensor;
use burn_wgpu::{AutoGraphicsApi, WgpuBackend};
use burn::backend::WgpuBackend;
// Type alias for the backend to use.
type Backend = WgpuBackend;
fn main() {
// Type alias to be cleaner
type Backend = WgpuBackend<AutoGraphicsApi, f32, i32>;
// Creation of two tensors, the first with explicit values and the second one with ones, with the same shape as the first
let tensor_1 = Tensor::<Backend, 2>::from_data([[2., 3.], [4., 5.]]);
let tensor_2 = Tensor::<Backend, 2>::ones_like(&tensor_1);

View File

@ -1,10 +1,27 @@
# Overview
This book will help you get started with the Burn deep learning framework.
Welcome to The Burn Book 👋
Although it is still in progress, it is planned to be divided into multiple sections, catering to
complete beginners and advanced users. For the time being, we offer an introductory guide in which
we perform training and inference on a simple model, while highlighting certain peculiarities of
Burn that set it apart from other frameworks.
This book will help you get started with the Burn deep learning framework, whether you are an
advanced user or a beginner. We have crafted some sections for you:
Throughout the book, we assume a basic understanding of Rust and deep learning concepts.
- [Basic Workflow: From Training to Inference](./basic-workflow): We'll start with the fundamentals,
guiding you through the entire workflow, from training your models to deploying them for
inference. This section lays the groundwork for your Burn expertise.
- [Building Blocks](./building-blocks): Dive deeper into Burn's core components, understanding how
they fit together. This knowledge forms the basis for more advanced usage and customization.
- [Custom Training Loop](./custom-training-loop): Gain the power to customize your training loops,
fine-tuning your models to meet your specific requirements. This section empowers you to harness
Burn's flexibility to its fullest.
- [Import ONNX Model](./import): Learn how to seamlessly import models from ONNX, expanding your
compatibility with other deep learning ecosystems.
- [Advanced](./advanced): Finally, venture into advanced topics, exploring Burn's capabilities at
their peak. This section caters to those who want to push the boundaries of what's possible with
Burn.
Throughout the book, we assume a basic understanding of deep learning concepts, but we may refer to
additional material when it seems appropriate.

View File

@ -11,13 +11,10 @@ repository = "https://github.com/burn-rs/burn/tree/main/burn-core"
version = "0.9.0"
[features]
default = ["std"]
default = ["std", "dataset-minimal"]
std = [
"autodiff",
"burn-common/std",
"dataset",
"burn-tensor/std",
"ndarray-std",
"flate2",
"log",
"rand/std",
@ -28,14 +25,16 @@ std = [
"half/std",
]
dataset = ["burn-dataset"]
dataset = ["burn-dataset/default"]
dataset-minimal = ["burn-dataset"]
dataset-sqlite = ["burn-dataset/sqlite"]
dataset-sqlite-bundled = ["burn-dataset/sqlite-bundled"]
# Backend
autodiff = ["burn-autodiff"]
ndarray = ["burn-ndarray"]
ndarray-std = ["ndarray", "burn-ndarray/std"]
ndarray = ["burn-ndarray/default"]
ndarray-no-std = ["burn-ndarray"]
ndarray-blas-accelerate = ["ndarray", "burn-ndarray/blas-accelerate"]
ndarray-blas-netlib = ["ndarray", "burn-ndarray/blas-netlib"]
ndarray-blas-openblas = ["ndarray", "burn-ndarray/blas-openblas"]
@ -45,7 +44,6 @@ wgpu = ["burn-wgpu"]
wgpu-autotune = ["wgpu", "burn-wgpu/autotune"]
tch = ["burn-tch"]
candle = ["burn-candle"]
# Serialization formats
@ -59,14 +57,14 @@ test-candle = ["candle"] # To use candle during testing, default uses ndarray.
# ** Please make sure all dependencies support no_std when std is disabled **
burn-autodiff = { path = "../burn-autodiff", version = "0.9.0", optional = true, features = [
"export_tests",
] }
burn-common = { path = "../burn-common", version = "0.9.0", default-features = false }
burn-dataset = { path = "../burn-dataset", version = "0.9.0", optional = true, default-features = false }
burn-derive = { path = "../burn-derive", version = "0.9.0" }
burn-tensor = { path = "../burn-tensor", version = "0.9.0", default-features = false }
# Backends
burn-ndarray = { path = "../burn-ndarray", version = "0.9.0", optional = true, default-features = false }
burn-autodiff = { path = "../burn-autodiff", version = "0.9.0", optional = true }
burn-wgpu = { path = "../burn-wgpu", version = "0.9.0", optional = true }
burn-tch = { path = "../burn-tch", version = "0.9.0", optional = true }
burn-candle = { path = "../burn-candle", version = "0.9.0", optional = true }
@ -97,3 +95,4 @@ burn-dataset = { path = "../burn-dataset", version = "0.9.0", features = [
] }
burn-ndarray = { path = "../burn-ndarray", version = "0.9.0", default-features = false }
burn-autodiff = { path = "../burn-autodiff", version = "0.9.0" }

View File

@ -11,7 +11,7 @@ repository = "https://github.com/burn-rs/burn/tree/main/burn-dataset"
version = "0.9.0"
[features]
default = []
default = ["sqlite-bundled"]
audio = [
"hound",

View File

@ -12,31 +12,32 @@ version = "0.9.0"
rust-version = "1.71"
[features]
default = [
"std",
"train-ui",
"train-metrics"
]
experimental-named-tensor = ["burn-core/experimental-named-tensor"]
std = [
"burn-core/std",
]
default = ["burn-core/default"]
std = ["burn-core/std"]
# Training requires std
train = ["std", "burn-train"]
# Includes the Text UI (progress bars, metric plots)
train-ui = ["train", "burn-train/ui"]
# Includes system info metrics (CPU/GPU usage, etc)
train-metrics = ["train", "burn-train/metrics"]
# Training with full features
train = ["burn-train/default", "autodiff", "dataset"]
## Include nothing
train-minimal = ["burn-train"]
## Includes the Text UI (progress bars, metric plots)
train-ui = ["burn-train/ui"]
## Includes system info metrics (CPU/GPU usage, etc)
train-metrics = ["burn-train/metrics"]
# Datasets
dataset = ["burn-core/dataset"]
dataset-minimal = ["burn-core/dataset-minimal"]
dataset-sqlite = ["burn-core/dataset-sqlite"]
dataset-sqlite-bundled = ["burn-core/dataset-sqlite-bundled"]
# Backends
autodiff = ["burn-core/autodiff"]
ndarray = ["burn-core/ndarray"]
ndarray-std = ["burn-core/ndarray-std"]
ndarray-no-std = ["burn-core/ndarray-no-std"]
ndarray-blas-accelerate = ["burn-core/ndarray-blas-accelerate"]
ndarray-blas-netlib = ["burn-core/ndarray-blas-netlib"]
ndarray-blas-openblas = ["burn-core/ndarray-blas-openblas"]
@ -46,9 +47,11 @@ wgpu = ["burn-core/wgpu"]
wgpu-autotune = ["burn-core/wgpu-autotune"]
tch = ["burn-core/tch"]
candle = ["burn-core/candle"]
# Experimental
experimental-named-tensor = ["burn-core/experimental-named-tensor"]
[dependencies]
# ** Please make sure all dependencies support no_std when std is disabled **

View File

@ -82,9 +82,6 @@ impl<G: GraphicsApi, F: FloatElement, I: IntElement> Backend for WgpuBackend<G,
// Create the output tensor primitive.
let output = WgpuTensor::new(lhs.context.clone(), shape_out, buffer);
let blocks_needed_in_x = f32::ceil(num_rows as f32 / workgroup_size_x as f32) as u32;
let blocks_needed_in_y = f32::ceil(num_cols as f32 / workgroup_size_y as f32) as u32;
// Compile the kernel or use the cache based on the template id.
let kernel = lhs.context.compile_dynamic(FusedMatmulAddRelu::<F>::new(
workgroup_size_x,
@ -98,6 +95,8 @@ impl<G: GraphicsApi, F: FloatElement, I: IntElement> Backend for WgpuBackend<G,
.create_buffer_with_data(bytemuck::cast_slice(&info));
// Declare the wgsl workgroup with the number of blocks in x, y and z.
let blocks_needed_in_x = f32::ceil(num_rows as f32 / workgroup_size_x as f32) as u32;
let blocks_needed_in_y = f32::ceil(num_cols as f32 / workgroup_size_y as f32) as u32;
let workgroup = WorkGroup::new(blocks_needed_in_x, blocks_needed_in_y, num_batches as u32);
// Execute lazily the kernel with the launch information and the given buffers.

View File

@ -6,11 +6,8 @@ name = "guide"
publish = false
version = "0.9.0"
[features]
default = ["burn/dataset-sqlite-bundled"]
[dependencies]
burn = {path = "../../burn", features=["autodiff", "wgpu"]}
burn = {path = "../../burn", features = ["train", "wgpu"]}
# Serialization
log = {workspace = true}

View File

@ -13,6 +13,6 @@ crate-type = ["cdylib"]
default = []
[dependencies]
burn = {path = "../../burn", default-features = false, features = ["ndarray"]}
burn = {path = "../../burn", default-features = false, features = ["ndarray-no-std"]}
serde = {workspace = true}
wasm-bindgen = "0.2.87"

View File

@ -8,7 +8,7 @@ version = "0.9.0"
[features]
default = ["burn/dataset-sqlite-bundled"]
ndarray = ["burn/ndarray-std"]
ndarray = ["burn/ndarray"]
ndarray-blas-accelerate = ["burn/ndarray-blas-accelerate"]
ndarray-blas-netlib = ["burn/ndarray-blas-netlib"]
ndarray-blas-openblas = ["burn/ndarray-blas-openblas"]

View File

@ -7,7 +7,7 @@ publish = false
version = "0.9.0"
[dependencies]
burn = {path = "../../burn", features = ["experimental-named-tensor", "ndarray-std"]}
burn = {path = "../../burn", features = ["experimental-named-tensor", "ndarray"]}
# Serialization
serde = {workspace = true, features = ["std", "derive"]}

View File

@ -10,7 +10,7 @@ version = "0.9.0"
default = ["burn/dataset-sqlite-bundled"]
[dependencies]
burn = {path = "../../burn", features=["ndarray-std"]}
burn = {path = "../../burn", features=["ndarray"]}
serde = {workspace = true}
[build-dependencies]

View File

@ -9,7 +9,7 @@ version = "0.9.0"
[features]
default = ["burn/dataset-sqlite-bundled"]
f16 = []
ndarray = ["burn/ndarray-std"]
ndarray = ["burn/ndarray"]
ndarray-blas-accelerate = ["burn/ndarray-blas-accelerate"]
ndarray-blas-netlib = ["burn/ndarray-blas-netlib"]
ndarray-blas-openblas = ["burn/ndarray-blas-openblas"]
@ -19,7 +19,7 @@ wgpu = ["burn/wgpu"]
[dependencies]
# Burn
burn = {path = "../../burn", features=["autodiff", "ndarray-std"]}
burn = {path = "../../burn", features=["autodiff", "ndarray"]}
# Tokenizer
tokenizers = { version = "0.13.4", default-features = false, features = [