Skip to content

Commit 52771cf

Browse files
committed
docs: refine faq dataloader and gpu guidance
1 parent 75341a0 commit 52771cf

2 files changed

Lines changed: 82 additions & 23 deletions

File tree

docs/getting_started/faq.md

Lines changed: 68 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -57,47 +57,92 @@ These are starting points, not rules. For the detailed comparison by dataset siz
5757

5858
### Do I need a GPU?
5959

60-
No, but it helps significantly for larger datasets and more complex architectures. The short answer:
60+
No, DeepTab runs on CPU. Whether a GPU helps depends on your dataset more than on any single rule: the number of rows, the number of features (and how dense or high-cardinality they are), the model's per-batch cost, the batch size, and how many epochs you train all interact. The [Model Zoo Comparison Tables](../model_zoo/comparison_tables) give the per-model cost driver and rough crossover points; treat the guidance below as a starting heuristic, not a hard threshold.
6161

62-
- **MLP, ResNet, TabM, MambaTab**: train comfortably on CPU up to ~100K to 500K rows.
63-
- **Mambular, TabulaRNN, TabTransformer, NODE**: CPU is fine up to ~10K to 20K rows; GPU recommended beyond that.
64-
- **FTTransformer, AutoInt, MambAttention, ENODE, NDTF, TabR**: GPU recommended above ~5K to 10K rows.
65-
- **SAINT**: GPU strongly recommended above ~2K rows (row attention makes every batch expensive).
62+
As a practical rule, reach for a GPU when several of these hold at once:
6663

67-
For a full per-model breakdown including the cost driver for each architecture, see the [Model Zoo Comparison Tables](../model_zoo/comparison_tables) in the Model Zoo.
64+
- **Dense, wide data**: many numerical features per row, so each forward and backward pass does substantially more matrix work that parallelises well on a GPU.
65+
- **Long training runs**: more than ~100 epochs, where even a modest per-epoch speedup compounds into a large wall-clock difference.
66+
- **Larger batch sizes**: bigger batches expose more parallelism, which a GPU can absorb while a CPU saturates. Conversely, very small batches may not fill the device and can erase the benefit.
67+
- **Attention- or sequence-heavy architectures**: models whose cost grows faster than linearly with features or rows (for example `SAINT`'s row attention, or the transformer and recurrent families) hit the GPU-recommended regime at much smaller dataset sizes than `MLP`, `ResNet`, `TabM`, or `MambaTab`.
68+
69+
For small datasets, short runs, or the lightweight models above, CPU is usually fine and avoids data-transfer overhead. When in doubt, profile one configuration both ways and compare wall-clock time per epoch.
6870

6971
### How do I know if my GPU is being used?
7072

71-
Print the hardware DeepTab can see:
73+
Use two checks. First, see what hardware DeepTab can detect:
7274

7375
```python
7476
from deeptab import print_hardware_info
7577

7678
print_hardware_info()
7779
```
7880

79-
The report lists the CPU, any CUDA GPUs, the Apple Silicon MPS backend, and the `accelerator` DeepTab would pick by default. DeepTab uses the first available GPU automatically. If a GPU is listed but you're not seeing speedups, make sure you're training on a reasonably large dataset, since small batches may not benefit from GPU parallelism.
81+
The report lists the CPU, any CUDA GPUs, the Apple Silicon MPS backend, and the `accelerator` DeepTab would pick by default. This only tells you what is _available_, not what a given run actually used.
82+
83+
To confirm what a fitted estimator is _really_ running on, inspect its runtime info after `fit`:
84+
85+
```python
86+
model.fit(X, y)
87+
88+
info = model.runtime_info()
89+
print(info["accelerator"]) # e.g. "CUDAAccelerator", "MPSAccelerator", "CPUAccelerator"
90+
print(info["root_device"]) # e.g. "cuda:0", "mps:0", "cpu"
91+
print(info["device"]) # device the model parameters live on
92+
print(info["num_devices"]) # number of devices in use
93+
```
94+
95+
`model.summary()` prints the same device, precision, and accelerator fields in a readable block.
96+
97+
```{warning}
98+
By default DeepTab lets Lightning auto-select the best available accelerator, but an explicit `accelerator=` you pass to `fit()` always wins. If you accidentally pass `accelerator="cpu"`, training stays on the CPU even when a GPU is present, and `runtime_info()["accelerator"]` will report `"CPUAccelerator"`. Drop the argument (or set `accelerator="auto"`) to let DeepTab use the GPU.
99+
```
80100

81101
### Can I use DeepTab with PyTorch dataloaders?
82102

83103
```{note}
84-
The high-level API uses `TabularDataModule` internally, but you can access `TabularDataset` directly for custom data loading.
104+
For normal training you never build a `DataLoader` yourself: `model.fit(...)` constructs the `TabularDataModule` and its loaders internally. Reach for this lower-level path only when you need behaviour the estimator does not expose, such as a custom or weighted sampler, or running DeepTab data through your own training/evaluation loop.
85105
```
86106

87-
Yes. The internal `TabularDataModule` creates PyTorch `DataLoader` instances. If you need custom data loading logic, you can use `TabularDataset` directly:
107+
Yes. The estimator does not accept a custom `DataLoader` directly, but after `fit` the fitted data module exposes a ready-to-use, preprocessed `TabularDataset`. You can wrap that dataset in any `DataLoader` (with your own sampler) and run the fitted network on the batches yourself.
88108

89109
```python
90-
from deeptab.data import TabularDataset
91-
from torch.utils.data import DataLoader
110+
import torch
111+
from torch.utils.data import DataLoader, WeightedRandomSampler
112+
from deeptab.models import MambularClassifier
92113

93-
dataset = TabularDataset(
94-
cat_features_list=[...],
95-
num_features_list=[...],
96-
embeddings_list=None,
97-
labels=labels,
98-
)
114+
model = MambularClassifier()
115+
model.fit(X_train, y_train, max_epochs=1) # fits the preprocessor and builds the network
116+
117+
# The fitted data module holds the preprocessed training dataset
118+
dm = model._data_module
119+
dm.setup("fit")
120+
dataset = dm.train_dataset # a TabularDataset of preprocessed tensors
121+
122+
# Wrap it in your own DataLoader, e.g. to oversample minority classes
123+
sampler = WeightedRandomSampler(sample_weights, num_samples=len(dataset))
124+
dataloader = DataLoader(dataset, batch_size=128, sampler=sampler)
125+
```
126+
127+
Each item is a `((num_features, cat_features, embeddings), label)` tuple, the same format DeepTab uses internally, so the default `DataLoader` collation batches it without a custom `collate_fn`. Feed those batches into the fitted network for a custom training or scoring loop:
99128

100-
dataloader = DataLoader(dataset, batch_size=128, shuffle=True)
129+
```python
130+
net = model._task_model # the LightningModule (internal API)
131+
device = next(net.parameters()).device
132+
net.eval()
133+
134+
with torch.no_grad():
135+
for (num_features, cat_features, embeddings), labels in dataloader:
136+
num_features = [t.to(device) for t in num_features]
137+
cat_features = [t.to(device) for t in cat_features]
138+
embeddings = [t.to(device) for t in embeddings] if embeddings else None
139+
140+
logits = net(num_features, cat_features, embeddings)
141+
# compute your own loss / metrics, or collect predictions ...
142+
```
143+
144+
```{warning}
145+
`model._data_module` and `model._task_model` are internal attributes and may change between releases. For standard training and inference, prefer the estimator API (`fit`, `predict`, `evaluate`), which manages preprocessing, batching, and device placement for you.
101146
```
102147

103148
## Data and preprocessing
@@ -424,12 +469,12 @@ The estimator API handles this automatically.
424469

425470
### What's the difference between Mambular and MambaTab?
426471

427-
Both use Mamba (State Space Model) blocks, but differ in how they process features:
472+
Both use Mamba (State Space Model) blocks, but differ in how they present features to the block:
428473

429-
- **Mambular**: Sequential model. Processes features one at a time in sequence, learning dependencies between features.
430-
- **MambaTab**: Joint model. Applies Mamba to a concatenated representation of all features at once.
474+
- **Mambular**: embeds each feature into its own token, then runs Mamba over that sequence of feature tokens and pools the result. Modelling features as a sequence lets it capture richer interactions between them, at a higher compute cost.
475+
- **MambaTab**: concatenates all features and projects them through a single linear layer into one representation before the Mamba block. This is lighter and faster, but models feature interactions less explicitly.
431476

432-
Mambular tends to work better for datasets where feature order matters or where you want to learn sequential dependencies.
477+
Mambular is the stronger general-purpose choice, reach for MambaTab when you want a more compact, faster Mamba-based model.
433478

434479
### When should I use distributional regression (LSS)?
435480

docs/getting_started/installation.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,20 @@ Recommended accelerator: mps
4646
The report covers the CPU core count, CUDA GPUs, the Apple Silicon MPS backend,
4747
and the `accelerator` value DeepTab would pick by default.
4848

49+
DeepTab already selects the best available accelerator, so you usually set
50+
nothing. For portable scripts you can make this explicit with `accelerator="auto"`,
51+
which uses a GPU when present and falls back to the CPU otherwise:
52+
53+
```python
54+
# Uses CUDA or MPS when available, otherwise CPU
55+
model.fit(X_train, y_train, accelerator="auto", max_epochs=100)
56+
```
57+
58+
```{tip}
59+
Pin a specific backend (`"gpu"`, `"cuda"`, `"mps"`, or `"cpu"`) only to force
60+
one. Unlike `"auto"`, those raise an error if the device is not present.
61+
```
62+
4963
### NVIDIA GPUs (CUDA)
5064

5165
```python

0 commit comments

Comments
 (0)