# Define Use Case Source: https://docs.tracebloc.io/create-use-case/define Create, configure, and publish an AI use case on tracebloc in four steps. This guide walks you through the 4 key steps to create, publish, and manage an AI use case on the tracebloc platform. Make sure you have a [tracebloc client](/environment-setup/setup-guide) running and your data is ingested. Navigate to the [use cases section](https://ai.tracebloc.io/my-use-cases), click on the "+" on the top right corner and simply follow along. Use this documentation for context, clarification and examples when needed. ## Step 1: Initialize and Set Privacy Objective: Define the basics and visibility of your AI use case. * Title * Cover Image (optional): JPG or PNG (max. 25MB) * Task: Select the task, e.g. "Image Classification", "Object Detection", "Tabular Classification", etc. See the full list of [supported data types and tasks](/create-use-case/prerequisites#supported-data-types-and-tasks). In case your use case is not yet supported, please reach out to us at [support@tracebloc.io](mailto:support@tracebloc.io). * **Privacy Type:** Choose Public (visible to all users) or Private (invite-only visibility). Initialize Preview your use case tile on the right side of the interface. *** ## Step 2: Data & Evaluation Objective: Attach datasets and define the benchmarking logic. Data & Evaluation * **Training and test metadataset**: A metadataset is a reference to an ingested dataset that stores summary information such as the number of samples and columns. Select the training and test metadatasets that correspond to the datasets you ingested in the [Prepare Data](/create-use-case/prepare-dataset) step. * **Score**: Define which benchmark to use for evaluation (e.g. Accuracy, F1, etc.). In case your evaluation metric is not yet supported, please reach out to us at [support@tracebloc.io](mailto:support@tracebloc.io). * **Upload EDA File (Optional)**: Attach a .ipynb EDA file to help participants understand the data context. Explore [template use cases](https://ai.tracebloc.io/explore) for inspiration. ### Supported Metrics per Data Type and Task The tables below list all evaluation metrics grouped by task type. Each metric uses either **higher is better** or **lower is better** sort order on the leaderboard. #### Image Classification | Metric | Description | Sort Order | | -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ---------------- | | Accuracy | Proportion of predictions that exactly match the ground truth. Can be misleading on imbalanced datasets. | Higher is better | | Precision | Measures the proportion of predicted positives that are actually positive. Important when false positives are costly. | Higher is better | | Recall | Measures the proportion of actual positives correctly identified. Important when missing a positive instance is costly. | Higher is better | | F1 Score | Balances precision and recall into a single metric. Especially useful for imbalanced datasets. | Higher is better | | Loss | Quantifies the error between predicted outputs and actual values. A core metric used during training and optimization. | Lower is better | | Log Loss | Measures how well a model predicts probability estimates for each class. Penalizes overconfident incorrect predictions. | Lower is better | | AUC-ROC | Measures ability to distinguish between classes across all thresholds, independent of any single decision threshold. | Higher is better | | AUC-PR | Measures precision-recall balance across different thresholds. Especially useful for highly imbalanced datasets. | Higher is better | | Top-3 Accuracy | Measures how often the true class label appears among the model's top three predictions. | Higher is better | | Top-5 Accuracy | Measures how often the true class label appears among the model's top five predictions. | Higher is better | | Cohen's Kappa | Measures agreement between predicted and ground truth labels while accounting for chance agreement. | Higher is better | | Matthews Correlation Coefficient (MCC) | Classification quality using all parts of the confusion matrix. Balanced even with imbalanced classes. Ranges from -1 to 1. | Higher is better | | Quadratic Weighted Kappa (QWK) | Measures agreement between predicted and ground truth labels, penalizing larger disagreements more heavily. | Higher is better | | Brier Score | Mean squared difference between predicted probabilities and actual outcomes. | Lower is better | #### Text Classification | Metric | Description | Sort Order | | -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ---------------- | | Accuracy | Proportion of predictions that exactly match the ground truth. Can be misleading on imbalanced datasets. | Higher is better | | Precision | Measures the proportion of predicted positives that are actually positive. Important when false positives are costly. | Higher is better | | Recall | Measures the proportion of actual positives correctly identified. Important when missing a positive instance is costly. | Higher is better | | F1 Score | Balances precision and recall into a single metric. Especially useful for imbalanced datasets. | Higher is better | | F1 Weighted | Weights each class's F1 Score by its support (number of true instances). Suitable for imbalanced multi-class classification. | Higher is better | | Micro F1 | Aggregates true positives, false positives, and false negatives across all classes, treating every prediction equally. | Higher is better | | Loss | Quantifies the error between predicted outputs and actual values. A core metric used during training and optimization. | Lower is better | | Log Loss | Measures how well a model predicts probability estimates for each class. Penalizes overconfident incorrect predictions. | Lower is better | | AUC-ROC | Measures ability to distinguish between classes across all thresholds, independent of any single decision threshold. | Higher is better | | Hamming Loss | Measures the fraction of labels incorrectly predicted. Commonly used in multi-label classification tasks. | Lower is better | | Jaccard Score | Measures similarity between predicted and ground truth labels by comparing their intersection to their union. | Higher is better | | Cohen's Kappa | Measures agreement between predicted and ground truth labels while accounting for chance agreement. | Higher is better | | Matthews Correlation Coefficient (MCC) | Classification quality using all parts of the confusion matrix. Balanced even with imbalanced classes. Ranges from -1 to 1. | Higher is better | | Quadratic Weighted Kappa (QWK) | Measures agreement between predicted and ground truth labels, penalizing larger disagreements more heavily. | Higher is better | | Brier Score | Mean squared difference between predicted probabilities and actual outcomes. | Lower is better | #### Tabular Classification | Metric | Description | Sort Order | | -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | ---------------- | | Accuracy | Proportion of predictions that exactly match the ground truth. Can be misleading on imbalanced datasets. | Higher is better | | Precision | Measures the proportion of predicted positives that are actually positive. Important when false positives are costly. | Higher is better | | Recall | Measures the proportion of actual positives correctly identified. Important when missing a positive instance is costly. | Higher is better | | F1 Score | Balances precision and recall into a single metric. Especially useful for imbalanced datasets. | Higher is better | | Loss | Quantifies the error between predicted outputs and actual values. A core metric used during training and optimization. | Lower is better | | Log Loss | Measures how well a model predicts probability estimates for each class. Penalizes overconfident incorrect predictions. | Lower is better | | AUC | Measures ability to distinguish between positive and negative classes across all classification thresholds. | Higher is better | | AUC-ROC | Measures ability to distinguish between classes across all thresholds, independent of any single decision threshold. | Higher is better | | AUC-PR | Measures precision-recall balance across different thresholds. Especially useful for highly imbalanced datasets. | Higher is better | | Balanced Accuracy | Averages recall across all classes, ensuring each class contributes equally regardless of frequency. | Higher is better | | Specificity (True Negative Rate) | Measures the proportion of actual negatives correctly identified. Important when false positives must be minimized. | Higher is better | | NPV (Negative Predictive Value) | Measures the proportion of predicted negatives that are actually negative. Important when confirming absence matters. | Higher is better | | F-beta Score (beta = 0.5) | Balances precision and recall with more emphasis on precision. Suitable when false positives are more costly. | Higher is better | | F-beta Score (beta = 2) | Balances precision and recall with more emphasis on recall. Suitable when missing positive instances is more costly. | Higher is better | | Hamming Loss | Measures the fraction of labels incorrectly predicted. Commonly used in multi-label classification tasks. | Lower is better | | Jaccard Score | Measures similarity between predicted and ground truth labels by comparing their intersection to their union. | Higher is better | | Cohen's Kappa | Measures agreement between predicted and ground truth labels while accounting for chance agreement. | Higher is better | | Matthews Correlation Coefficient (MCC) | Classification quality using all parts of the confusion matrix. Balanced even with imbalanced classes. Ranges from -1 to 1. | Higher is better | | Quadratic Weighted Kappa (QWK) | Measures agreement between predicted and ground truth labels, penalizing larger disagreements more heavily. | Higher is better | | Brier Score | Mean squared difference between predicted probabilities and actual outcomes. | Lower is better | | Gini Coefficient | Measures discriminatory power between positive and negative classes. Closely related to AUC-ROC. | Higher is better | | Normalized Gini | Scales the Gini Coefficient relative to a perfect model, enabling fair comparison across datasets. Ranges from -1 to 1. | Higher is better | #### Object Detection | Metric | Description | Sort Order | | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ---------------- | | Accuracy | Proportion of predictions that exactly match the ground truth. | Higher is better | | Loss | Quantifies the error between predicted outputs and actual values. A core metric used during training and optimization. | Lower is better | | Mean Average Precision (mAP) | Evaluates the quality of ranked predictions. Commonly used in object detection and ranking tasks. | Higher is better | | Mean Average Precision @ IoU 0.50 | Evaluates object detection requiring at least 50% overlap between predicted and ground truth bounding boxes. | Higher is better | | Mean Average Precision @ IoU 0.75 | Stricter variant requiring at least 75% overlap between predicted and ground truth bounding boxes. | Higher is better | | mAP per Class | Reports Average Precision individually for each object class. Helps identify which classes the model struggles with. | Higher is better | | Intersection over Union (IoU) | Measures overlap between predicted and ground truth regions. Used for localization accuracy. | Higher is better | | GIoU (Generalized IoU) | Extends standard IoU by penalizing non-overlapping predictions using the smallest enclosing box. Ranges from -1 to 1. | Higher is better | | Mean Average Recall @ 1 Detection | Measures how well the model retrieves ground truth objects when only the single top-scoring detection is allowed. | Higher is better | | Mean Average Recall @ 10 Detections | Measures retrieval of ground truth objects when up to 10 detections per image are allowed. | Higher is better | #### Semantic Segmentation | Metric | Description | Sort Order | | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ---------------- | | Accuracy | Proportion of predictions that exactly match the ground truth. | Higher is better | | Precision | Measures the proportion of predicted positives that are actually positive. | Higher is better | | Recall | Measures the proportion of actual positives correctly identified. | Higher is better | | F1 Score | Balances precision and recall into a single metric. | Higher is better | | Loss | Quantifies the error between predicted outputs and actual values. | Lower is better | | Intersection over Union (IoU) | Measures overlap between predicted and ground truth regions. | Higher is better | | Mean Intersection over Union (mIoU) | Averages IoU across all classes, evaluating how well a model predicts each class region. | Higher is better | | Frequency Weighted IoU | Weights each class's IoU by its relative frequency in the ground truth, giving more importance to dominant classes. | Higher is better | | Dice Coefficient | Measures similarity between predicted and ground truth segmentation regions. Especially sensitive to small structures. | Higher is better | | Pixel Accuracy | Proportion of correctly classified pixels across the entire image. Can be dominated by frequent classes. | Higher is better | | Mean Pixel Accuracy | Averages pixel accuracy per class, giving equal importance to all classes regardless of frequency. | Higher is better | | Boundary IoU | Measures how well predicted segmentation boundaries align with ground truth boundaries. Focuses on edge accuracy. | Higher is better | | Boundary F1 Score | Combines boundary precision and recall to evaluate how accurately predicted boundaries match ground truth edges. | Higher is better | | Hausdorff Distance | Maximum distance between predicted and ground truth boundaries. Captures the worst-case boundary mismatch. | Lower is better | | Average Surface Distance (ASD) | Average distance between predicted and ground truth boundary points. Stable measure of overall boundary alignment. | Lower is better | #### Instance Segmentation | Metric | Description | Sort Order | | --------- | -------------------------------------------------------------------------- | ---------------- | | Accuracy | Proportion of predictions that exactly match the ground truth. | Higher is better | | Precision | Measures the proportion of predicted positives that are actually positive. | Higher is better | | Recall | Measures the proportion of actual positives correctly identified. | Higher is better | | F1 Score | Balances precision and recall into a single metric. | Higher is better | | Loss | Quantifies the error between predicted outputs and actual values. | Lower is better | #### Keypoint Detection | Metric | Description | Sort Order | | ------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | ---------------- | | Precision | Measures the proportion of predicted positives that are actually positive. | Higher is better | | Recall | Measures the proportion of actual positives correctly identified. | Higher is better | | F1 Score | Balances precision and recall into a single metric. | Higher is better | | Loss | Quantifies the error between predicted outputs and actual values. | Lower is better | | Mean Absolute Error (MAE) | Average magnitude of errors between predicted and actual values, expressed in the same units as the target. | Lower is better | | PCK (Percentage of Correct Keypoints) | Measures how accurately predicted keypoints fall within a specified distance of ground truth. | Higher is better | | PCK\@0.05 | Keypoints within a normalized distance threshold of 0.05 from ground truth. Strictest variant. | Higher is better | | PCK\@0.10 | Keypoints within a normalized distance threshold of 0.10 from ground truth. | Higher is better | | PCK\@0.20 | Keypoints within a normalized distance threshold of 0.20 from ground truth. | Higher is better | | PCK\@0.30 | Keypoints within a normalized distance threshold of 0.30 from ground truth. | Higher is better | | PCK\@0.50 | Keypoints within a normalized distance threshold of 0.50 from ground truth. Most lenient variant. | Higher is better | | Object Keypoint Similarity (OKS) | Measures similarity between predicted and ground truth keypoints, accounting for scale and localization uncertainty. | Higher is better | | Mean Per Joint Position Error (MPJPE) | Average Euclidean distance between predicted and ground truth joint positions. Standard for pose estimation. | Lower is better | | Visibility Accuracy | Measures how correctly the model predicts the visibility status of keypoints, independent of spatial localization. | Higher is better | #### Tabular Regression | Metric | Description | Sort Order | | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | ---------------- | | Accuracy | Proportion of predictions that exactly match the ground truth. | Higher is better | | Loss | Quantifies the error between predicted outputs and actual values. | Lower is better | | Mean Absolute Error (MAE) | Average magnitude of errors between predicted and actual values, expressed in the same units as the target. | Lower is better | | Mean Squared Error (MSE) | Average squared difference between predicted and actual values. Penalizes larger errors more heavily. | Lower is better | | Root Mean Squared Error (RMSE) | Square root of MSE, expressing prediction error in the same units as the target variable. | Lower is better | | R² (Coefficient of Determination) | Measures how well a regression model explains variance in the target. A value of 1.0 indicates perfect prediction. | Higher is better | | Root Mean Squared Logarithmic Error (RMSLE) | Measures error on a logarithmic scale. Useful when target values span several orders of magnitude. | Lower is better | | Median Absolute Error (Median AE) | Uses the median of absolute errors instead of the mean. Highly robust to outliers. | Lower is better | | Explained Variance | Measures how well the model captures the variance of the target, independent of systematic bias. Ranges up to 1.0. | Higher is better | | Mean Bias Error (MBE) | Measures the average bias in predictions. Positive = overestimation, negative = underestimation. | Lower is better | #### Time Series Forecasting | Metric | Description | Sort Order | | ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------- | ---------------- | | Accuracy | Proportion of predictions that exactly match the ground truth. | Higher is better | | Loss | Quantifies the error between predicted outputs and actual values. | Lower is better | | Mean Absolute Error (MAE) | Average magnitude of errors between predicted and actual values, expressed in the same units as the target. | Lower is better | | Mean Squared Error (MSE) | Average squared difference between predicted and actual values. Penalizes larger errors more heavily. | Lower is better | | Root Mean Squared Error (RMSE) | Square root of MSE, expressing prediction error in the same units as the target variable. | Lower is better | | R² (Coefficient of Determination) | Measures how well a regression model explains variance in the target. A value of 1.0 indicates perfect prediction. | Higher is better | | Root Mean Squared Logarithmic Error (RMSLE) | Measures error on a logarithmic scale. Useful when target values span several orders of magnitude. | Lower is better | | Mean Absolute Percentage Error (MAPE) | Average percentage difference between predicted and actual values. Easy to interpret across different scales. | Lower is better | | Symmetric Mean Absolute Percentage Error (SMAPE) | Symmetric variant of MAPE that reduces issues when actual values are close to zero. | Lower is better | | Median Absolute Percentage Error (MdAPE) | Uses the median of absolute percentage errors. More robust to outliers. | Lower is better | | Theil's U (U2 Statistic) | Measures forecasting accuracy relative to a naive benchmark. Values below 1.0 mean the model outperforms the baseline. | Lower is better | | Max Error | Captures the single largest absolute difference between predicted and actual values. | Lower is better | | Direction Accuracy | Measures how often the model correctly predicts the direction of change (up or down) between consecutive values. | Higher is better | #### Time-to-Event Prediction | Metric | Description | Sort Order | | --------------------------- | ------------------------------------------------------------------------------------------------------------------------ | ---------------- | | F1 Score | Balances precision and recall into a single metric. | Higher is better | | Concordance Index (C-Index) | Measures how well predicted risk scores agree with the observed ordering of event times. Standard for survival analysis. | Higher is better | *** ## Step 3: Describe Your Use Case Objective: Describe your use case and objective in detail. Provide a clear description that helps participants understand the problem, the data context, and the goal. Cover what the data represents, what a good model should achieve, and any domain-specific considerations participants should be aware of. Browse published use cases in the [Explore section](https://ai.tracebloc.io/explore) for examples of well-written descriptions. Describe *** ## Step 4: Review & Submit Objective: Set collaboration and resource constraints. Add emails of vendors, colleagues, or researchers. Invitations are sent once the use case is saved or published. For instructions for data scientists about how to join your use case, follow the [join a use case guide](/join-use-case/join-use-case). Review & Submit ### Compute Assignment Define training budget in PFLOPs. Example: 10 participants × 200 PFLOPs each = 2,000 PFLOPs Cost Calculation: 2,000 PFLOPs × €0.025 = €50.00 Always allocate more resources than minimum requirements and monitor resource usage regularly. You can stop or adjust training at any time. ### Final Step: Publish or Save as Draft Use "Publish" to go live or "Save as Draft" to continue editing later. You can now see your use case in the [use cases section](https://ai.tracebloc.io/my-use-cases). *** ## Next Steps Once your use case is published, reach out to external vendors, your colleagues or data scientists to train models on your use case. In the use case view, monitor * total resource consumption * daily submits and user activity * overall leaderboard and submissions Once models have been submitted, you can [compare them in the leaderboard section](/create-use-case/evaluate-models) of a use case. *** ## Need Help? * Email us at [support@tracebloc.io](mailto:support@tracebloc.io) # Evaluate models Source: https://docs.tracebloc.io/create-use-case/evaluate-models Compare vendor models side by side on the leaderboard. Navigate to the Leaderboard section of your use case to compare submitted models, for example the [Breast Cancer Screening Use Case](https://ai.tracebloc.io/explore/ai-breast-cancer-screening-and-image-classification?tab=leaderboard). ## The Leaderboard Vendors are ranked by the score of their best performing model. Scores are calculated using the evaluation metric you selected when [defining the use case](/create-use-case/define#supported-metrics-per-data-type-and-task) (e.g. Accuracy, F1, mAP). Leaderboard ### Leaderboard Columns | Column | Description | | ------------------ | --------------------------------------------------------------------------------- | | Rank | Position based on the best model score. Lower rank = better performance. | | Team / Vendor | The participant or team that submitted the model. | | Score | The model's evaluation result on your test data, using the metric you defined. | | Model Size | Size of the submitted model in parameters or MB. Useful for comparing efficiency. | | Energy Consumption | Compute resources consumed during training. Helps assess cost-efficiency. | | Submissions | Total number of models submitted by the team. | | Remaining Budget | How much of the allocated compute budget (in PFLOPs) the team has left. | ### Actions You Can Take From the use case view, you can: * **Compare models** — Use the leaderboard to identify the best performing and most efficient models side by side. * **Stop or adjust training** — Reduce or revoke a team's remaining compute budget to control costs or end a round of evaluation. * **Contact participants** — Reach out to vendors or researchers directly to discuss results, request further iterations, or negotiate next steps. * **Select a winner** — Once evaluation is complete, choose the best model based on score, model size, and resource efficiency. *** ## Supported Evaluation Metrics Scores on the leaderboard are calculated using the metric you selected when defining the use case. See the full list of [supported metrics per data type and task](/create-use-case/define#supported-metrics-per-data-type-and-task). *** ## Next Steps * Browse ready-made examples: [Templates](/create-use-case/templates) *** ## Need Help? * Email us at [support@tracebloc.io](mailto:support@tracebloc.io) # Prepare Data Source: https://docs.tracebloc.io/create-use-case/prepare-dataset Learn how to prepare and ingest your datasets into tracebloc using containerized data ingestors. Complete guide for CSV, image, and text data with Kubernetes deployment steps. ## Overview Make your data available to the Kubernetes cluster so it can be used for training and evaluation. Whether your client runs on Azure, AWS, Google Cloud, or a local Minikube setup, the process of ingesting datasets works the same way. The data ingestor is a lightweight service that bridges your raw data and the cluster's persistent storage. Every supported task has a [dataset template](/create-use-case/templates) — the folder layout, the labels CSV and a ready-to-edit `ingest.yaml` — that you lay your own data out against. By containerizing the ingestion step, the ingestor validates data format and schema, enforces consistency, and transfers the dataset securely into cluster's SQL storage where it becomes accessible to all training and evaluation jobs. This guide covers: * Laying your data out to match the dataset template for your task (tabular, images, text, time series) * Deploying the data ingestor for training and test data using Kubernetes * Managing datasets through the tracebloc interface **IMPORTANT** Make sure that the data format and ML task is supported and that data standards are met by reviewing the [docs](/create-use-case/prerequisites). You must run the process twice, once to ingest training and once to ingest testing data. ## Setup options You can ingest data into your client in two ways: * **Declarative YAML (recommended, simpler)** — describe your dataset in \~8 lines of `ingest.yaml`, then `helm install`. No Dockerfile, no custom Python script. The official ingestor image runs it for you. Use this for any dataset that fits a supported category. * **Custom Python script + Kubernetes Job (advanced)** — install the `tracebloc-ingestor` Python package, write a short ingestion script against it, build and push a Docker image, then `kubectl apply` an `ingestor-job.yaml`. Use this when the declarative schema can't express what your data needs — e.g. non-trivial preprocessing, a custom validator, or a `BaseProcessor` subclass. Start with the declarative method below. Drop down to the custom-script flow only if you need it. ## Declarative YAML (recommended) Describe your dataset in \~8 lines of YAML, then `helm install`. The official ingestor image (published as `ghcr.io/tracebloc/ingestor`) runs it. No Dockerfile, no Python script. **Before you run any commands in this section:** if you installed the client via the one-liner (`curl -fsSL https://tracebloc.io/i.sh | bash`), every later `helm upgrade tracebloc/client …` **must** include `--reset-then-reuse-values`, otherwise the upgrade drops the values the installer applied and breaks the workspace: ```bash theme={null} helm upgrade tracebloc/client -n --reset-then-reuse-values ``` Append `--version ` to pin a specific chart version. This caveat only affects upgrades of the parent `tracebloc/client` chart, not the `helm install tracebloc/ingestor` runs below. ### 1. Add the chart repo (one-time) ```bash theme={null} helm repo add tracebloc https://tracebloc.github.io/client helm repo update ``` The `tracebloc/client` parent chart bootstraps the cluster (jobs-manager, MySQL, RBAC). The `tracebloc/ingestor` subchart submits per-dataset ingestion runs against it. ### 2. Stage your data on the cluster's shared PVC The chart **doesn't transport data into the cluster** — it points at data already accessible to the cluster's shared PVC (`client-pvc` by default, mounted at `/data/shared/` inside the ingestor Pod). Before installing, get your raw files there. For a single-node workspace (the default install), the PVC is backed by a host directory the installer created at `~/.tracebloc//data/`. Drop your files into a per-dataset subdirectory: ```bash theme={null} # Host path on the machine where the tracebloc client is installed. # Pick a per dataset — it becomes the path you reference in ingest.yaml. mkdir -p ~/.tracebloc//data/ cp -R LOCAL_PATH/images ~/.tracebloc//data// cp LOCAL_PATH/labels.csv ~/.tracebloc//data// ``` Inside the ingestor Pod those files appear at `/data/shared//...` — that's what you'll put in `ingest.yaml` below. For multi-node or EKS deployments where the PVC isn't backed by a local host path, use a throwaway `kubectl cp` Pod or a cloud-storage init container instead. See the [client ingestor README](https://github.com/tracebloc/client/blob/develop/ingestor/README.md#stage-your-data-on-the-shared-pvc) for those recipes. ### 3. Write your `ingest.yaml` The example below is for `image_classification`. **Other tasks require different fields** — e.g. `tabular_classification` has no `images:` and instead needs a typed `schema:` block. Don't copy this one blindly; open the [dataset template for your task](/create-use-case/templates) — one page per task with the folder layout, the CSV columns, a ready-to-edit `ingest.yaml` and the checks the ingestor runs — and edit from there. ```yaml theme={null} apiVersion: tracebloc.io/v1 kind: IngestConfig category: image_classification table: cats_dogs_train intent: train csv: /data/shared/cats-dogs/labels.csv images: /data/shared/cats-dogs/images/ label: label ``` The top-level shape (`apiVersion`, `kind`, `category`, `table`, `intent`, `label`) is the same for every category; the `category` field picks the validator set, file-extension defaults, and column conventions. The data-source fields (`csv:`, `images:`, `schema:`, …) vary per category. The paths are *paths inside the ingestor Pod*, which is the PVC mount you populated in step 2. ### 4. Install once per dataset The ingestor runs once: validates your data, copies files into the destination directory on the PVC, inserts rows into MySQL, sends metadata to the tracebloc backend, then exits. **Run it twice per dataset** — once with `intent: train`, once with `intent: test` — using distinct `table:` names. The example below shows both releases: ```bash theme={null} # Train release — points at the ingest.yaml from step 3 (table: cats_dogs_train, intent: train) helm install cats-dogs-train tracebloc/ingestor \ --namespace \ --set-file ingestConfig=./ingest-train.yaml # Test release — same shape, with table: cats_dogs_test and intent: test helm install cats-dogs-test tracebloc/ingestor \ --namespace \ --set-file ingestConfig=./ingest-test.yaml ``` Each `helm install` is a separate release (the first argument is the release name), so the two runs don't collide. The ingestor Pod picks up `CLIENT_ID` / `CLIENT_PASSWORD` automatically from the Kubernetes Secret the parent `tracebloc/client` chart created in `` at install time — you don't pass credentials on the `helm install` command. **Validation error like `'' is not one of [...]` or `Additional properties are not allowed ( was unexpected)`?** This comes from the cluster's `jobs-manager` validating against its own bundled schema at submit time — the deployed schema is older than the ingestor image you're installing. `helm repo update` won't fix it (that only refreshes the local chart index, not the running server). The fix is on the cluster side: upgrade the parent chart so jobs-manager redeploys with the current schema. ```bash theme={null} helm upgrade tracebloc/client \ -n --reset-then-reuse-values ``` Then re-run the `helm install` command above. Full chart docs (data-staging recipe, schema, every category, update model, verification, override knobs) → [client ingestor README](https://github.com/tracebloc/client/blob/develop/ingestor/README.md). ## Custom Python script (advanced) Use this flow when the declarative schema can't express what your data needs — typically when you have non-trivial preprocessing logic, a custom validator, or a `BaseProcessor` subclass. The sections below — Quick Setup and Detailed Setup — both describe this advanced path. ## Quick Setup Use this quick setup if you already have an ingestor configured and just want to switch datasets or toggle between training and testing. If you are setting up for the first time, go to the next section for the detailed walkthrough. ### Steps 1. Edit your ingestion script (the one you wrote in [Configure a script](#1-configure-a-script) below) * Update csv options and data\_path * Only for tabular data: Update schema * Set `schema` and `CSVIngestor()`parameters like category, intent, label\_column, etc. to match data type, task and train/test purpose ```python theme={null} ingestor = CSVIngestor( ... category=TaskCategory.TABULAR_CLASSIFICATION, # Adjust for your task csv_options=csv_options, # Defined above label_column="ColumnName", # Target column intent=Intent.TRAIN, # TRAIN or TEST ) ``` 2. Build and push docker image: Make sure Docker is running on your system (e.g. by starting Docker Desktop), then execute the following command: ```bash theme={null} # Build for cloud (multi-arch) and push directly to registry docker buildx build --platform linux/amd64,linux/arm64 -t /: --push . ``` 3. Edit ingestor-job.yaml: * `metadata.name`: Unique job name (e.g. ingestor-job-train and ingestor-job-test) * `image`: The tag you built and pushed * `LABEL_FILE`: Path inside the pod to the labels CSV, under the PVC mount (e.g. `/data/shared/labels.csv`). For tabular data, this is the same file that contains both labels and features. * `TABLE_NAME`: Unique table name (no spaces, one per dataset). Title is optional * `SRC_PATH`: Root of the mounted dataset directory inside the pod (`/data/shared`, backed by `~/.tracebloc//data` on the client host) 4. Deploy to Kubernetes ```bash theme={null} `kubectl apply -f ingestor-job.yaml -n ` ``` ## Detailed Setup ### 1. Configure a script This section walks you through the step-by-step setup of a data ingestor. You will install the ingestor package, lay your data out against the dataset template for your task, and write a short ingestion script that matches it. Follow this guide if you are setting up an ingestor for the first time or need full control beyond the quick setup. ### Install the ingestor package The ingestion library is published on PyPI as `tracebloc-ingestor` (import name `tracebloc_ingestor`). It is the same code the official ingestor image runs, so a script written against it behaves exactly like the declarative path. It needs Python 3.11 or newer: ```bash theme={null} pip install tracebloc-ingestor ``` **IMPORTANT:** Datasets must be cleaned and preprocessed before ingestion. Participants cannot view, clean or fix raw data, so model performance will only be as good as the data you provide. ### Pick the dataset template for your task Open the [dataset template](/create-use-case/templates) for your task. It gives you the folder layout and the labels CSV the ingestor expects — lay your data out the same way, then set the matching `category` and `data_format` in your script. The rows below cover the most common tasks; every other task on the templates index works the same way, and its `TaskCategory` constant is the upper-cased `category` identifier from its page (for example `keypoint_detection` → `TaskCategory.KEYPOINT_DETECTION`). | Data Type | Dataset template | Data Category | Data Format | | --------- | ---------------------------------------------------------------------------------------- | --------------------------------------- | -------------------- | | Tabular | [Tabular classification](/create-use-case/templates/tabular-classification) | `TaskCategory.TABULAR_CLASSIFICATION` | `DataFormat.TABULAR` | | Tabular | [Tabular regression](/create-use-case/templates/tabular-regression) | `TaskCategory.TABULAR_REGRESSION` | `DataFormat.TABULAR` | | Tabular | [Time-series forecasting](/create-use-case/templates/time-series-forecasting) | `TaskCategory.TIME_SERIES_FORECASTING` | `DataFormat.TABULAR` | | Tabular | [Survival analysis (time-to-event)](/create-use-case/templates/time-to-event-prediction) | `TaskCategory.TIME_TO_EVENT_PREDICTION` | `DataFormat.TABULAR` | | Image | [Image classification](/create-use-case/templates/image-classification) | `TaskCategory.IMAGE_CLASSIFICATION` | `DataFormat.IMAGE` | | Image | [Object detection](/create-use-case/templates/object-detection) | `TaskCategory.OBJECT_DETECTION` | `DataFormat.IMAGE` | | Text | [Text classification](/create-use-case/templates/text-classification) | `TaskCategory.TEXT_CLASSIFICATION` | `DataFormat.TEXT` | #### High Level Script Structure Every ingestion script follows the same structure — save it as `ingestor.py` next to your Dockerfile: ```python theme={null} import logging from tracebloc_ingestor import Config, Database, APIClient, CSVIngestor, run_ingestion from tracebloc_ingestor.utils.logging import setup_logging from tracebloc_ingestor.utils.constants import TaskCategory, Intent, DataFormat config = Config() setup_logging(config) logger = logging.getLogger(__name__) def main(): # Initialize components database = Database(config) # Initialize API client api_client = APIClient(config) # Define csv_options and schema (schema is only needed for tabular data) csv_options = {...} schema = {...} # Initialize ingestor ingestor = CSVIngestor(...) # Run and ingest data run_ingestion(ingestor, config.LABEL_FILE, batch_size=config.BATCH_SIZE, logger=logger) if __name__ == "__main__": main() ``` Both Database, APIClient and other values are configured automatically from the environment variables defined in `ingestor_job.yaml`. * `config.LABEL_FILE`: Path to local csv label file * `config.BATCH_SIZE`: Batch size used during ingestion ### Customize the script The structure above is a starting point, but every dataset has its own format and labels. In this step you adapt the script to your data by tuning CSV ingestion options and setting the ingestor parameters (category, label column, intent, data path and schema). The following example shows how to ingest a tabular dataset, but the setup works the same way for image or text data. #### Needed for Tabular Data: Define Schema Define the dataset schema as a Python dictionary, mapping each column to its SQL type and constraints. Do not include IDs or the label column into the schema. ```python theme={null} # Schema definition for tabular data schema = { "feature_00": "FLOAT ", "feature_01": "FLOAT ", "feature_02": "FLOAT ", ... } ``` #### Needed for Image Classification Data: Define Image Options Define image size and file extension. ```python theme={null} # Image specific options including CSV options image_options = { # Image processing options "target_size": (512, 512), # Define image size. Height = Width "extension": FileExtension.JPG, # allowed extension for images: jpeg, jpg, png } ``` #### Needed for Object Detection Data: Define Image Options Define file extension. ```python theme={null} # Object detection specific options including CSV options object_detection_options = { # Image processing options "target_size": (448, 448), # Resize images to this fixed dimension. Dimension is not changeable. "extension": FileExtension.JPG, # allowed extension for images: jpeg, jpg, png } ``` #### Needed for Text Data: Define File Extension Define file extensions. ```python theme={null} text_options = {"extension": FileExtension.TXT} # Allowed text file extensions ``` #### Set CSV ingestion options Customize parsing, memory handling, and data cleaning with the csv\_options dictionary: ```python theme={null} csv_options = { "chunk_size": 1000, # Process rows in batches for efficiency "delimiter": ",", # Column separator "quotechar": '"', # Quoted field character "escapechar": "\\", # Escape character for quotes "encoding": "utf-8", # File encoding "on_bad_lines": "warn", # Log malformed rows instead of failing "skip_blank_lines": True, # Ignore empty rows "na_values": ["", "NA", "NULL", "None"] # Treat these as missing values } ``` #### Set Up the Ingestor Define the Ingestor instance with the required configuration. See the tabular data example below: ```python theme={null} ingestor = CSVIngestor( database=database, # From ingestor-job.yaml api_client=api_client, # From ingestor-job.yaml table_name=config.TABLE_NAME, # From ingestor-job.yaml schema=schema, # Defined above, only needed for tabular data data_format=DataFormat.TABULAR, # Set the data format for the task category=TaskCategory.TABULAR_CLASSIFICATION, # Adjust for your task csv_options=csv_options, # Defined above file_options={"number_of_columns": len(schema)}, # Don´t change label_column="ColumnName", # Target column intent=Intent.TRAIN, # TRAIN or TEST ) ``` **Specify:** * `category`, choose the ML task type (TABULAR\_CLASSIFICATION, IMAGE\_CLASSIFICATION, OBJECT\_DETECTION) * `label_column`, target column or class labels * `intent`, set as TRAIN or TEST depending on dataset purpose * include `file_options` or `schema` depending on the data type Other data types work similarly — follow the same configuration pattern with the `category`, `data_format` and options for your task from the table above. ### 2. Build Docker Image With your script configured, the next step is to package it into a Docker image so it can run inside the Kubernetes cluster. ### Docker Hub Setup (first-time users) The cluster pulls your ingestor image from a public Docker registry, so you need an account before you can push. If you already have one, skip to [Write the Dockerfile](#write-the-dockerfile). 1. **Create a Docker Hub account** at [hub.docker.com/signup](https://hub.docker.com/signup) and verify your email. 2. **Log in from your terminal** so the `docker push` command can authenticate: ```bash theme={null} docker login ``` 3. **Push the data ingestor image** to your account using the build/push commands in the next section. The image name takes the form `/:` — the username segment must match the account you just created. 4. **Make the image public** so the cluster can pull it without credentials: * Go to [hub.docker.com/repositories](https://hub.docker.com/repositories), open the repository you just pushed. * Click **Settings → Visibility settings → Make public**. Keeping the image private is also fine, but then you must create a Kubernetes `imagePullSecret` named `regcred` in the client namespace (the `ingestor-job.yaml` already references it). ### Place data files on the client host Datasets are **not** baked into the Docker image. They live on the client host in the per-workspace data directory and are mounted into the ingestor pod through the shared PVC (`client-pvc` → `/data/shared`). Copy your dataset into the client's data directory, where `` is the workspace name you chose during client install (which is also the Helm release name and the Kubernetes namespace — the chart uses the same value for all three). The directory `~/.tracebloc//data/` is created automatically by the installer; just drop your files into it: ```bash theme={null} # Host path on the machine where the tracebloc client is installed. # HOST_DATA_DIR defaults to ~/.tracebloc; override only if you set it during install. cp -R LOCAL_PATH/images ~/.tracebloc//data/ cp LOCAL_PATH/labels.csv ~/.tracebloc//data/ ``` Inside the ingestor pod this directory is mounted at `/data/shared`, so the same files appear as `/data/shared/images/...` and `/data/shared/labels.csv`. Set `SRC_PATH` and `LABEL_FILE` in `ingestor-job.yaml` to point at those in-pod paths (see [Configure Kubernetes](#3-configure-kubernetes) below). For tabular data the same rule applies — drop the single `labels.csv` (with features and labels) into `~/.tracebloc//data/`. ### Write the Dockerfile The Dockerfile only needs to install the ingestor package and copy in your script — the dataset is mounted at runtime, so do **not** `COPY` data into the image: ```dockerfile theme={null} FROM python:3.11-slim WORKDIR /app RUN pip install --no-cache-dir tracebloc-ingestor # Copy the ingestion script into /app COPY ingestor.py /app/ingestor.py # Set the entrypoint ENTRYPOINT ["python", "/app/ingestor.py"] ``` If the cluster enforces the `restricted` Pod Security Standard (see [Run as non-root](#run-as-non-root) below), also add a non-root user to the Dockerfile, **before** the `# Set the entrypoint` line: ```dockerfile theme={null} RUN groupadd -g 1000 app && \ useradd -u 1000 -g 1000 -m -s /bin/bash app && \ chown -R 1000:1000 /app USER 1000 # Set the entrypoint ``` ### Build Docker Image You need a docker user and password to proceed with the next step. Cloud platforms run a mix of x86 and ARM nodes (e.g. AWS Graviton, Azure Ampere, GCP Tau T2A). Building a multi-arch image with `--platform linux/amd64,linux/arm64` guarantees the image runs on either, particularly if you build on Apple Silicon (M1/M2) or other ARM-based systems. Build and push the image with a single command: ```bash theme={null} docker buildx build --platform linux/amd64,linux/arm64 -t /: --push . ``` ### 3. Configure Kubernetes With the image generated and pushed to the registry, edit `ingestor-job.yaml` with your settings: ```yaml theme={null} apiVersion: batch/v1 kind: Job metadata: name: # Set a job name e.g. ingestor-job-train namespace: # Use the client namespace spec: template: spec: containers: - name: api image: /:latest # Your Docker image name and tag, e.g. "latest" imagePullPolicy: Always # Use IfNotPresent only for local tests # Required if the namespace enforces the `restricted` Pod Security Standard. # See "Run as non-root" below. securityContext: allowPrivilegeEscalation: false runAsNonRoot: true capabilities: drop: - "ALL" seccompProfile: type: RuntimeDefault volumeMounts: - name: shared-volume mountPath: "/data/shared" # Client shared PVC. Backed by ~/.tracebloc//data on the client host — read your dataset from here env: # Client credentials - name: CLIENT_ENV value: "prod" - name: CLIENT_ID # Client credentials from tracebloc dashboard value: - name: CLIENT_PASSWORD # Client credentials from tracebloc dashboard value: # Storage configuration - name: CLIENT_PVC # value has to match the shared data PVC name in the client values.yaml value: "client-pvc" # MySQL configuration - name: MYSQL_HOST # value has to match the mysql deployment name in the client values.yaml value: "mysql-client" # Dataset information — paths inside the ingestor pod. # /data/shared is the mount of the client-pvc, which is backed by # ~/.tracebloc//data on the client host. - name: SRC_PATH value: "/data/shared" # Root of the mounted dataset directory - name: LABEL_FILE value: "/data/shared/labels.csv" # Path to the labels CSV inside the pod - name: TABLE_NAME value: # Different for train and test, no spaces - name: TITLE value: # Optional - name: BATCH_SIZE value: "4000" # Optional, defaults to 4000 - name: LOG_LEVEL value: "DEBUG" # Set DEBUG, "WARNING", "INFO" or "ERROR" imagePullSecrets: - name: regcred volumes: - name: shared-volume persistentVolumeClaim: claimName: client-pvc # value has to match the shared data PVC name in the client values.yaml restartPolicy: Never ``` **Specify:** * `JOBNAME`, to distinguish between train and test data jobs. * `NAMESPACE`, use the same as your client. * `image`, your Docker image (imagePullPolicy: Always for DockerHub, IfNotPresent for local) * `CLIENT_ID`, `CLIENT_PASSWORD` from the [tracebloc client view](https://ai.tracebloc.io/clients) * `TABLE_NAME`, unique per dataset, train and test use different names, no spaces. Different names for train and test data is mandatory * `LABEL_FILE`, path inside the ingestor pod (under `/data/shared`) to the CSV with file paths and labels — must match the location of the file you placed in `~/.tracebloc//data/` * `SRC_PATH`, root inside the pod where the dataset directory is mounted (`/data/shared`) * `BATCH_SIZE` is the number of entries sent to the server per request. Optional — defaults to 4000. Keep it consistent across data types. It depends on available CPU memory, not for example image size. Too large can exhaust memory. It was tested up to 10,000, but 5,000 is a safe default for most systems. * `LOG_LEVEL`, "WARNING" for all warnings and errors, "INFO" for all logs, "ERROR" for errors only ### 4. Deploy Run the ingestor as a Kubernetes Job: ```bash theme={null} kubectl apply -f ingestor-job.yaml -n kubectl wait -n --for=condition=complete job/ kubectl logs -n job/ # Delete the job only after verifying logs kubectl delete -n job/ ``` This will start a pod, run the ingestion process once, and once complete you can delete the job. **IMPORTANT:** You must run this process twice — once for training data and once for test data. Use different `JOBNAME` and `TABLE_NAME` values for each run (e.g. `ingestor-job-train` / `ingestor-job-test`), and set `intent` to `TRAIN` or `TEST` accordingly in your ingestion script. ### Run as non-root If the namespace enforces the `restricted` [Pod Security Standard](https://kubernetes.io/docs/concepts/security/pod-security-standards/), `kubectl apply` will be admitted but the pod will be rejected with a warning like: ```text theme={null} Warning: would violate PodSecurity "restricted:latest": allowPrivilegeEscalation != false (container "api" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "api" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "api" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "api" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost") job.batch/ingestor-job-train-data created ``` Two changes are needed: **1. Add a `securityContext` block to the container in `ingestor-job.yaml`** (already shown in the YAML above): ```yaml theme={null} securityContext: allowPrivilegeEscalation: false runAsNonRoot: true capabilities: drop: - "ALL" seccompProfile: type: RuntimeDefault ``` **2. Run the container as a non-root user.** Add the following to the Dockerfile **before** the `# Set the entrypoint` line so the image ships with a UID that satisfies `runAsNonRoot: true`: ```dockerfile theme={null} RUN groupadd -g 1000 app && \ useradd -u 1000 -g 1000 -m -s /bin/bash app && \ chown -R 1000:1000 /app USER 1000 ``` Rebuild and push the image, then re-apply the job. The data ingestor always runs a validation step before ingestion and moving files. #### Verify Deployment Verify if jobs and pods are deployed successfully and running: ```bash theme={null} kubectl get jobs,pods -n kubectl logs -n ``` Look for "All records processed successfully" in the logs. ## Dataset Management Interface View your datasets at [ai.tracebloc.io/data](https://ai.tracebloc.io/data) after successful deployment. **Interface displays:** * Dataset name, ID, and record count * Data type (Tabular, Image, Text) and purpose (Training/Testing) * Namespace and GPU requirements ## Best Practices * Deploy jobs for training and testing simultaneously using different job names * Use consistent, descriptive table names (e.g., `insurance-claims-train`, `insurance-claims-test`) * Validate data schemas before deployment to prevent ingestion failures * Clean data before ingestion - Participants cannot view, clean, or fix raw data, so model performance depends entirely on the quality of data you provide ## Troubleshooting **Recommended for debugging:** Use [k9s](https://k9scli.io/), a terminal-based Kubernetes dashboard, to monitor jobs, pods, and logs in real time. Run `k9s -n ` to get a live view of resources, switch between them instantly, and inspect logs or events with a few keystrokes. Compared to kubectl, it is faster and more convenient. **Stale Kubernetes Job preventing new Job execution:** ```bash theme={null} kubectl delete job ingestor-job -n kubectl logs ``` **Storage Issues:** ```bash theme={null} kubectl get pvc -n ``` *** ## Next Steps * Define and publish your use case: [Define Use Case](/create-use-case/define) *** ## Need Help? * Email us at [support@tracebloc.io](mailto:support@tracebloc.io) # Prerequisites Source: https://docs.tracebloc.io/create-use-case/prerequisites Supported data types, tasks, and requirements for creating a use case on tracebloc. tracebloc is continually expanding supported data types and tasks to enable your use cases. In case your use case is not yet supported, please reach out to us at [support@tracebloc.io](mailto:support@tracebloc.io). Before you can create a use case on the [tracebloc website](https://ai.tracebloc.io/my-use-cases), make sure the following requirements are met: * You are registered as a user on the tracebloc platform * You have a client deployed using kubernetes either [locally or in the cloud](/environment-setup/setup-guide) * Your dataset is cleaned and preprocessed * You are familiar with the supported data types and tasks Once these requirements are met, proceed with: * [Preparing and ingesting the dataset](/create-use-case/prepare-dataset) * [Defining the use case](/create-use-case/define) * [Setting evaluation metrics](/create-use-case/define#supported-metrics-per-data-type-and-task) * [Evaluating models](/create-use-case/evaluate-models) ## Supported Data Types and Tasks The exact folder layout, CSV columns, `ingest.yaml` and validation rules for each task are on the [dataset template pages](/create-use-case/templates). Where this overview and a template page differ, the template page is authoritative — it is derived from the ingestor's own checks. ### Image Data **Requirements for all image data tasks:** Uniform image sizes and uniform file types. For example all images as 256x256 rgb .jpg files. Convert files if necessary and in case your images do not fit the supported size, crop or resize accordingly. **Filenames in the label CSV:** For all image and text tasks, the `filename` column in the label CSV **must not include the file extension** (e.g. use `cat01`, not `cat01.jpg`). The extension is configured once on the ingestor side via `file_options.extension` in the template and applied to every row at ingestion time. All images are validated before ingestion by the data ingestor. The ingestion process only starts when every file meets the requirements. Fix or remove any invalid images, then retry. | Task | Input file type | Color mode | Supported image size | Label file type | Requirements | Links | | --------------------- | --------------- | ------------------------------------------------------------ | ----------------------- | --------------- | ----------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | | Classification | PNG, JPG, JPEG | rgb (3 channels) or grayscale (1 channel), 8-bit per channel | Square (height = width) | CSV | Uniform image size and file type per dataset | [Detailed structure](#image-classification)
[Template](/create-use-case/templates/image-classification) | | Keypoint Detection | PNG, JPG, JPEG | rgb (3 channels) or grayscale (1 channel), 8-bit per channel | Square (height = width) | CSV | Uniform image sizes
Same number of keypoints per image and class | [Detailed structure](#image-keypoint-detection)
[Template](/create-use-case/templates/keypoint-detection) | | Object Detection | PNG, JPG, JPEG | rgb (3 channels) or grayscale (1 channel), 8-bit per channel | Square (height = width) | Pascal VOC | Uniform image sizes, one xml per image | [Detailed structure](#image-object-detection)
[Template](/create-use-case/templates/object-detection) | | Semantic Segmentation | PNG, JPG, JPEG | rgb (3 channels) or grayscale (1 channel), 8-bit per channel | Square (height = width) | PNG, JPG, JPEG | Uniform image and mask sizes | [Detailed structure](#image-semantic-segmentation)
[Template](/create-use-case/templates/semantic-segmentation) | ### Image Classification ```structure theme={null} train/ labels.csv images/ cat01.jpg dog02.jpg ... test/ ... ``` ```labels.csv theme={null} filename,label cat01,cat dog02,dog ... ``` The `filename` column must not include the file extension. Set the expected extension once via `file_options.extension` in the ingestor template. ### Image Keypoint Detection The number of keypoints per class and per image must be fixed. For example, in a person/car keypoint detection project, both classes must define the same keypoints, and every image must contain the full set for its class. You cannot mix classes with different keypoint counts (e.g., 16 for person and 32 for car) or annotate some images with fewer keypoints for the same class. ```structure theme={null} train/ annotations.csv images/ image01.png image02.png ... test/ ... ``` ```annotations.csv theme={null} filename,label,x,y,visibility image01,person,100,150,2 image01,car,120,140,1 image02,person,95,155,0 image02,car,115,145,2 ``` * **X and Y** determine the X-/Y-coordinates of a keypoint * **Visibility** indicates whether a keypoint is visible in the image or not: 0 = not visible (point outside the image or point is in the image but occluded), 1 = visible * **Filename** should not include the file extension. ### Image Object Detection The filename like "street01.png" specifies the link between images and annotations. XML-file annotations are in Pascal VOC format. The labels.csv contains a global list of all images and objects. ```structure theme={null} train/ labels.csv images/ street01.png street02.png ... annotations/ street01.xml street02.xml ... test/ ... ``` ```xml theme={null} street01.jpg car 100 200 300 400 ... ``` Each row represents one detected object, not one image. An image with multiple objects will have multiple rows. ```labels.csv theme={null} filename,image_label street01,car street01,car street01,person street02,car ... ``` The `filename` column links each row to its image and to the matching XML annotation file. The `image_label` column holds the class name for each object instance — one row per object. Filenames should not include the file extension. ### Image Semantic Segmentation Each mask is an rgb image whose pixel values map to classes defined in labels.csv. The labels.csv contains a global list per image and class. All masks must exactly match their corresponding image sizes and file names. For binary segmentation (two classes), provide a single-channel grayscale mask where background pixels are black (0) and foreground pixels are white (255). For three or more classes, supply an RGB mask where each class is represented by a unique color (or pixel value). The filename should not include the file extension. ```structure theme={null} train/ labels.csv images/ scene01.png scene02.png ... masks/ scene01.png scene02.png ... test/ ... ``` ```labels.csv theme={null} filename,mask_filename,label,colour image1,mask1,road,#FFFFFF image1,mask1,background,#000000 image2,mask2,background,#000000 image2,mask2,road,#FFFFFF ... ``` ### Tabular Data **Requirements for all tabular data tasks:** Each dataset must be provided as a single CSV file with a header row. Every column must contain uniform data types, for example numeric values for features and a categorical or alphanumeric column for labels. Use UTF-8 encoding with comma separators and validate that your schema matches the expected types. Invalid rows are skipped by the ingestor. | Task | Data file type | Requirements | Links | | ------------------------ | ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | | Classification | CSV (features and label in one single file) | Uniform data formats per column.
Feature columns: Numeric
Label columns: Alphanumeric | [Detailed structure](#tabular-classification)
[Template](/create-use-case/templates/tabular-classification) | | Regression | CSV (features and label in one single file) | Uniform data formats per column.
Feature columns: Numeric
Label column: Numeric (continuous target) | [Detailed structure](#tabular-regression)
[Template](/create-use-case/templates/tabular-regression) | | Time Series Forecasting | CSV (timestamp, features and target in one single file) | A timestamp column in a parsable format (e.g. `YYYY-MM-DD` or ISO 8601).
Feature columns: Numeric
Target column: Numeric | [Detailed structure](#time-series-forecasting)
[Template](/create-use-case/templates/time-series-forecasting) | | Time to Event Prediction | CSV (features, time and event in one single file) | A `time` column (duration until event or censoring, integer or numeric).
An event column (binary 0/1 indicating whether the event occurred).
Feature columns: Numeric | [Detailed structure](#time-to-event-prediction)
[Template](/create-use-case/templates/time-to-event-prediction) | ### Tabular Classification Include a header row with clear column names, using a dedicated column for the labels. An `id` column is recommended but not required. ```csv theme={null} id,feature1,feature2,feature3,label 1,1.5,2.3,0.8,class_a 2,2.1,1.9,1.2,class_b 3,0.9,3.1,0.5,class_a ... ``` ### Tabular Regression Same structure as Tabular Classification, but the label column holds a continuous numeric target (not a class). ```csv theme={null} id,square_feet,bedrooms,age,price 1,1668.08,3,15,285.50 2,1701.78,4,12,320.75 3,1697.01,2,8,245.30 ... ``` ### Time Series Forecasting Provide a single CSV with a timestamp column, one or more numeric feature columns, and the numeric target column you want to forecast. Rows must be ordered by time and use a consistent timestamp format. ```csv theme={null} timestamp,feature_1,feature_2,target 2023-10-01,7,1,125.50 2023-10-02,1,0,132.30 2023-10-03,2,0,128.75 ... ``` ### Time to Event Prediction Provide a single CSV with feature columns, a `time` column (duration to event or censoring), and a binary event column (1 = event occurred, 0 = censored). ```csv theme={null} age,feature_1,feature_2,time,event 75,0,1.9,4,1 55,0,1.1,6,1 65,0,1.3,7,0 ... ``` ### Text Data | Task | Input files | Label file type | Requirements | Links | | -------------- | ----------- | --------------- | -------------------------- | ----------------------------------------------------------------------------------------------------------- | | Classification | TXT | CSV | Text file may not be empty | [Detailed structure](#text-classification)
[Template](/create-use-case/templates/text-classification) | ### Text Classification The `filename` column must not include the file extension. The extension is set once via `file_options.extension` in the ingestor template (e.g. `FileExtension.TXT`). ```structure theme={null} train/ labels.csv texts/ review01.txt review02.txt ... test/ ... ``` ```labels.csv theme={null} filename,label review01,positive review02,negative ... ``` ```text file example theme={null} # review01.txt This product is amazing! I love it. ``` *** ## Next Steps * Prepare and ingest your dataset: [Prepare Data](/create-use-case/prepare-dataset) *** ## Need Help? * Email us at [support@tracebloc.io](mailto:support@tracebloc.io) # Dataset templates Source: https://docs.tracebloc.io/create-use-case/templates The dataset layout, ingest.yaml and validation rules for every task tracebloc supports — one page per task, ready to copy. Every task tracebloc supports has a dataset template: the exact folder layout the data ingestor expects, a labels or data CSV in the right shape, a ready-to-edit `ingest.yaml`, and the list of checks the ingestor runs before a single row is stored. Pick your task below, lay your data out the same way, and follow [Prepare Data](/create-use-case/prepare-dataset) to run the ingest. ## Templates by task | Data | Task | Template | | ----------- | --------------------------------- | ---------------------------------------------------------------------------- | | Image | Image classification | [Layout and config](/create-use-case/templates/image-classification) | | Image | Object detection | [Layout and config](/create-use-case/templates/object-detection) | | Image | Keypoint detection | [Layout and config](/create-use-case/templates/keypoint-detection) | | Image | Semantic segmentation | [Layout and config](/create-use-case/templates/semantic-segmentation) | | Text | Text classification | [Layout and config](/create-use-case/templates/text-classification) | | Text | Token classification | [Layout and config](/create-use-case/templates/token-classification) | | Text | Sentence-pair classification | [Layout and config](/create-use-case/templates/sentence-pair-classification) | | Text | Masked language modeling | [Layout and config](/create-use-case/templates/masked-language-modeling) | | Text | Causal language modeling | [Layout and config](/create-use-case/templates/causal-language-modeling) | | Text | Sequence-to-sequence | [Layout and config](/create-use-case/templates/seq2seq) | | Text | Embeddings | [Layout and config](/create-use-case/templates/embeddings) | | Tabular | Tabular classification | [Layout and config](/create-use-case/templates/tabular-classification) | | Tabular | Tabular regression | [Layout and config](/create-use-case/templates/tabular-regression) | | Time series | Time-series forecasting | [Layout and config](/create-use-case/templates/time-series-forecasting) | | Time series | Time-series classification | [Layout and config](/create-use-case/templates/time-series-classification) | | Time series | Survival analysis (time-to-event) | [Layout and config](/create-use-case/templates/time-to-event-prediction) | ## How the templates fit together Every template follows the same three steps. The task pages only spell out what differs. 1. **Stage the files** on the shared data volume of your secure environment. Inside the ingestor they appear under `/data/shared/`; how to get them there is covered in [Prepare Data](/create-use-case/prepare-dataset#2-stage-your-data-on-the-clusters-shared-pvc). 2. **Write `ingest.yaml`** from the task page. The top of the file is identical for every task; the `category` field names the task and decides which folders, columns and checks apply. 3. **Run the ingest once per split** — once with `intent: train` and once with `intent: test`, each with its own `table` name: ```bash theme={null} helm install tracebloc/ingestor \ --namespace \ --set-file ingestConfig=./ingest.yaml ``` The ingestor validates the whole dataset first, then copies files, stores rows and registers only metadata with the platform. Raw data never leaves your infrastructure. If any check fails, nothing is stored. ## Where files must live For tasks with one file per sample (images and text), the ingestor reads every file from a **fixed subfolder name** next to the others: `images/`, `annotations/`, `masks/`, `texts/` or `sequences/`. It derives the dataset root from the folder you name in `ingest.yaml` (the parent of `images:`, `texts:`, and so on), so keep the subfolders side by side and spelled exactly like that: ```text theme={null} /data/shared// ├── labels.csv # the manifest (any name; point `csv:` at it) ├── images/ # or texts/ or sequences/ — the per-sample files └── annotations/ # only object detection (masks/ only semantic segmentation) ``` Tabular and time-series tasks have no per-sample files: the CSV named in `csv:` is the whole dataset. ## The `ingest.yaml` contract These fields are shared by every task. Task-specific fields (`images`, `texts`, `schema`, `target_size`, ...) are explained on the task pages. | Field | Required | Meaning | | ----------------------------------------------------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `apiVersion` | yes | Always `tracebloc.io/v1`. | | `kind` | yes | Always `IngestConfig`. | | `category` | yes | The task. One of the 16 identifiers in the table above (for example `image_classification`). | | `table` | yes | Name of the dataset table in your secure environment. Letters, digits and underscores only; must start with a letter or underscore. Use a different name for the train and test splits, and a new name for every new version — the ingestor refuses to write into a table folder that already holds data. | | `intent` | yes | `train` or `test`. | | `csv` | one of `csv` / `json` | Path (inside the ingestor) to the labels CSV or, for tabular tasks, the data CSV. Object detection has neither — see its page. | | `json` | one of `csv` / `json` | Path to a JSON manifest (a top-level array of records, or one object) instead of a CSV. | | `label` | depends on task | Either the column name (`label: label`) or an object `{column, policy}`. Regression-class tasks require the object form with an explicit `policy` (`bucket` or `passthrough` — see [Label policy](#label-policy-for-regression-class-tasks)); self-supervised text tasks must not set it at all. See each task page. | | `schema` | tabular, time-series, semantic segmentation | Map of column name to SQL type. See [SQL types](#sql-types-for-schema). | | `data_id` | no | How each stored row gets its id. `strategy: content_hash` (default) hashes the row content with a salt that never leaves your secure environment, so a retried run re-uses its rows instead of duplicating them; identical source rows collapse into one. `strategy: uuid` gives every row a fresh id. `strategy: column` with `column: ` copies a column of yours — only safe when that column carries no personal data. | | `spec.csv_options` | no | `chunk_size` (default 1000), `delimiter` (`,`), `quotechar` (`"`), `escapechar` (`\`). Files are always read as UTF-8. | | `spec.file_options` | no | `extension` (one of `.jpg`, `.jpeg`, `.png`, `.txt`, `.text`, `.xml`), `target_size` (`[width, height]`), `min_size` (`[width, height]`, default `[32, 32]`). Per-task defaults are listed on each page. | | `columns` | no | Per-column facts the platform cannot infer, used when datasets are combined: `unit` (for example `years`, `USD`) and `ordinal` (category values in order, low to high). | | `color_mode`, `bit_depth` | no | Image tasks: `RGB` or `grayscale`; `8` or `16`. | | `language`, `normalization` | no | Text tasks: the dataset language (for example `en`) and the text normalization you applied (for example `lowercase`). | | `time_unit`, `event_indicator` | no | Survival analysis: `days`, `weeks`, `months` or `years`, and the integer codes for an observed event and a censored case. | | `positive_definition` | no | Embeddings: what counts as a positive pair. | | `spec.validators`, `spec.sidecars`, `spec.processors` | no | Accepted by the schema but **not executed** by the current ingestor — it logs a warning and continues with the task defaults. Leave them out. | ## Rules that apply to every CSV * The file must be valid UTF-8 without NUL bytes. Excel users: save as **CSV UTF-8**. * Surrounding whitespace in header names is stripped; duplicate header names are rejected. * The label column you configure is matched case- and whitespace-insensitively (`Label` satisfies `label: label`). * Tasks with one file per sample need a column named exactly `filename` (lowercase). Its value may include the file extension or not: `cat1.jpeg` and `cat1` both resolve to `images/cat1.jpeg` when the configured extension is `.jpeg`. A value that already ends in `.jpeg`, `.jpg`, `.png`, `.xml`, `.txt` or `.text` (any case) is used as is. * The manifest must contain at least one data row, and at least one referenced file must exist. * String labels have surrounding whitespace stripped before storage. Only a label that is missing from the record is stored as NULL; an empty or whitespace-only label is stored as the empty string `""`. The NA tokens below apply to `schema` columns only — in a label column that is not declared in `schema`, an empty cell is `""` and `NA` or `null` is a genuine class value. * The `id` column in the sample CSVs is not stored unless you declare it in `schema` — and you cannot declare it under that name. These column names are reserved by the ingestor and must not appear in `schema`: `id`, `created_at`, `updated_at`, `status`, `data_intent`, `data_id`, `filename`, `extension`, `annotation`, `ingestor_id`. The label column is not declared in `schema` either — `label:` names it. * Column names may be at most 64 characters. Any other character is allowed. ## Checks every ingest runs Task-specific checks are listed on each page. These run for every task: | Check | What it rejects | | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- | | Ingestable records | A CSV with a header but no rows; a per-sample-file task whose manifest lacks an exact `filename` column, or whose referenced files are all missing. | | Label diversity | A classification dataset with fewer than 2 distinct label values (after whitespace stripping). Not run for regression-class or self-supervised tasks. | | Table name | A `table` outside `^[a-zA-Z_][a-zA-Z0-9_]*$`. Common SQL keywords produce a warning. | | Duplicate | A destination folder for this `table` that already contains data. Duplicate `filename` values within the manifest produce a warning. | ## Label policy for regression-class tasks Tabular regression, time-series forecasting and survival analysis have a numeric target, and the platform must never receive raw target values. Their `label` therefore needs the object form with an explicit `policy`: ```yaml theme={null} label: column: price policy: bucket ``` `bucket` replaces each value with one of 64 stable hash buckets **in the metadata sent to the platform only**. The rows stored in your secure environment keep the raw value, which is what training reads. A missing target is reported as bucket `-1`. `passthrough` sends raw values and is only appropriate when you have cleared that with your compliance owner. ## SQL types for `schema` `VARCHAR(n)`, `CHAR(n)`, `TEXT`, `INT`, `INTEGER`, `TINYINT`, `SMALLINT`, `MEDIUMINT`, `BIGINT`, `FLOAT`, `DOUBLE`, `DECIMAL(p,s)`, `NUMERIC(p,s)`, `BOOLEAN`, `BOOL`, `DATE`, `DATETIME`, `TIMESTAMP`, `TIME`, `BLOB`, `LONGBLOB`. Type names are case-insensitive. A near-miss (`INTERGER`) is rejected with a "did you mean" hint. Every declared column is checked against its type across the whole file: non-numeric values in numeric columns, values over a `VARCHAR` length, `inf`, integers outside the 64-bit range and unparseable dates all fail the ingest. In `schema` columns, empty cells and exactly these tokens are stored as NULL: `NA`, `N/A`, `n/a`, `NULL`, `null`, `None`, `none`, `NaN`, `nan`, ``, `#N/A`. The match is case-sensitive — `Null`, `NONE`, `NAN` or `#n/a` are ordinary values and fail the type check in a numeric column. ## Next steps * Run the ingest: [Prepare Data](/create-use-case/prepare-dataset) * Define and publish your use case: [Define Use Case](/create-use-case/define) ## Need help? Email [support@tracebloc.io](mailto:support@tracebloc.io). # Causal language modeling Source: https://docs.tracebloc.io/create-use-case/templates/causal-language-modeling Dataset template for causal language modeling: raw text or prompt/completion pairs, one per .txt, a manifest CSV without labels, ingest.yaml and the checks the data ingestor runs. Predict the next word. This task is **self-supervised**: there is no label. Each sample is one `.txt` file of raw text in one of two shapes: * **Pretraining** — the whole file is plain text. * **Instruction tuning (SFT)** — one line of the form `promptcompletion`. Everything before the first tab is the prompt, everything after is the completion. A dataset may mix both shapes. The ingestor does not enforce either shape; it only checks that files are valid text. ## Folder layout ```text theme={null} /data/shared/dolly-clm/ ├── labels.csv └── texts/ ├── clm_0000001.txt # plain text ├── clm_0000002.txt # plain text ├── clm_0000004.txt # promptcompletion └── ... ``` * The folder is named `texts` (raw text) and sits next to the manifest CSV. * UTF-8 encoded; one extension across the dataset (`.txt` by default). ## Manifest CSV ```csv theme={null} filename clm_0000001 clm_0000002 clm_0000003 ``` | Column | Required | Meaning | | ----------- | ---------------------- | ------------------------------------------------------------------- | | `filename` | yes, exactly this name | The text file, with or without extension. | | `extension` | no | Present in the shipped sample (`'.txt'`); not read by the ingestor. | There is no label column. Setting `label:` in `ingest.yaml` is rejected. ## ingest.yaml ```yaml theme={null} apiVersion: tracebloc.io/v1 kind: IngestConfig category: causal_language_modeling table: dolly_clm_train intent: train csv: /data/shared/dolly-clm/labels.csv texts: /data/shared/dolly-clm/texts/ ``` | Field | Required | Meaning | | ----------------------------- | ------------------- | ------------------------------------------- | | `csv` | yes | Path to the manifest CSV. | | `texts` | yes | The `texts/` folder. | | `label` | **must not be set** | Self-supervised task. | | `schema` | no | Extra typed columns only. Never `filename`. | | `spec.file_options.extension` | no | `.txt` (default) or `.text`. | | `language`, `normalization` | no | Dataset language and applied normalization. | ## What the ingestor checks | Check | Rejects | | ------------ | ------------------------------------------------------------------------------------- | | File type | Files under `texts/` with a different extension than configured, or mixed extensions. | | Text content | NUL bytes or invalid UTF-8; empty files produce a warning. | | Data types | With a `schema`: values that do not match their declared type. | Plus the [checks every ingest runs](/create-use-case/templates#checks-every-ingest-runs), except label diversity (no label). No tokenizer is needed at ingest; the ingestor records a data-derived text profile (script mix and length distribution, never the text) for the platform's tokenizer-fit warning. ## Sample dataset The template ships five files: three plain-text passages and two `promptcompletion` pairs, with a five-row manifest. The `ingest.yaml` above ingests it with no overrides. ## Next steps * Stage the data and run the ingest: [Prepare Data](/create-use-case/prepare-dataset) * Shared rules for every template: [Dataset templates](/create-use-case/templates) # Embeddings Source: https://docs.tracebloc.io/create-use-case/templates/embeddings Dataset template for contrastive embedding training: anchor/positive pairs or anchor/positive/negative triplets, one per .txt, ingest.yaml and the checks the data ingestor runs. Learn vector representations from text pairs. This task is **self-supervised** (contrastive): there is no label column — the pairing is the supervision. Each sample is one `.txt` file with one tab-separated record: * a **pair** `anchorpositive` — two texts that should embed close together, or * a **triplet** `anchorpositivenegative` — with a hard negative that should embed far from the anchor. Pairs and triplets may be mixed in one dataset. ## Folder layout ```text theme={null} /data/shared/stsb-embeddings/ ├── labels.csv └── texts/ ├── emb_0000001.txt # anchorpositive ├── emb_0000004.txt # anchorpositivenegative └── ... ``` Example pair: ```text theme={null} How do I reset my password? What are the steps to recover my account login? ``` * The folder is named `texts` and sits next to the manifest CSV. * Exactly one tab between fields, all fields non-empty, one record per file on a single line. Unlike the other self-supervised text tasks, this structure **is enforced**. * UTF-8 encoded; one extension across the dataset (`.txt` by default). ## Manifest CSV ```csv theme={null} filename emb_0000001 emb_0000002 emb_0000003 ``` | Column | Required | Meaning | | ----------- | ---------------------- | ------------------------------------------------------------------- | | `filename` | yes, exactly this name | The text file, with or without extension. | | `extension` | no | Present in the shipped sample (`'.txt'`); not read by the ingestor. | There is no label column. Setting `label:` in `ingest.yaml` is rejected. ## ingest.yaml ```yaml theme={null} apiVersion: tracebloc.io/v1 kind: IngestConfig category: embeddings table: stsb_embeddings_train intent: train csv: /data/shared/stsb-embeddings/labels.csv texts: /data/shared/stsb-embeddings/texts/ ``` | Field | Required | Meaning | | ----------------------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | | `csv` | yes | Path to the manifest CSV. | | `texts` | yes | The `texts/` folder. | | `label` | **must not be set** | No label column. | | `positive_definition` | no | Free text describing what makes a pair positive (for example `paraphrase`), recorded for consistency checks when datasets are combined. | | `schema` | no | Extra typed columns only. Never `filename`. | | `spec.file_options.extension` | no | `.txt` (default) or `.text`. | | `language`, `normalization` | no | Dataset language and applied normalization. | ## What the ingestor checks | Check | Rejects | | ----------------- | ------------------------------------------------------------------------------------------------------------------- | | File type | Files under `texts/` with a different extension than configured, or mixed extensions. | | Text content | NUL bytes or invalid UTF-8; empty files produce a warning. | | Contrastive pairs | A referenced file that is missing, spans several lines, has a field count other than 2 or 3, or has an empty field. | | Data types | With a `schema`: values that do not match their declared type. | Plus the [checks every ingest runs](/create-use-case/templates#checks-every-ingest-runs), except label diversity (no label). ## Sample dataset The template ships three pairs and two triplets with a five-row manifest. The `ingest.yaml` above ingests it with no overrides. ## Next steps * Stage the data and run the ingest: [Prepare Data](/create-use-case/prepare-dataset) * Shared rules for every template: [Dataset templates](/create-use-case/templates) # Image classification Source: https://docs.tracebloc.io/create-use-case/templates/image-classification Dataset template for image classification: folder layout, labels CSV, ingest.yaml and the checks the data ingestor runs. Sort images into classes. Each sample is one image file plus one row in a labels CSV that names the file and its class. ## Folder layout ```text theme={null} /data/shared/cats-dogs/ ├── labels.csv └── images/ ├── cat1.jpeg ├── cat2.jpeg ├── dog1.jpeg └── ... ``` * The image folder must be named `images` and sit next to the labels CSV. * Every image in the dataset must have the **same extension** and the **same width and height**. Mixed extensions or mixed resolutions fail the ingest. * Supported extensions: `.jpg`, `.jpeg`, `.png`. The default is `.jpeg`; override it with `spec.file_options.extension`. * The ingestor copies images as they are. It does not resize them — bring them to the target size before you ingest. ## Labels CSV ```csv theme={null} filename,label cat1.jpeg,cat cat2.jpeg,cat dog1.jpeg,dog dog2.jpeg,dog ``` | Column | Required | Meaning | | ---------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------- | | `filename` | yes, exactly this name | The image file, with or without extension (`cat1` resolves to `images/cat1.jpeg` under the default extension). | | `label` | yes | The class of the image. Any column name works — set it with `label:`. At least two distinct classes are required. | Extra columns are ignored unless you declare them in `schema`. ## ingest.yaml ```yaml theme={null} apiVersion: tracebloc.io/v1 kind: IngestConfig category: image_classification table: cats_dogs_train intent: train csv: /data/shared/cats-dogs/labels.csv images: /data/shared/cats-dogs/images/ label: label ``` | Field | Required | Meaning | | ----------------------------- | -------- | ------------------------------------------------------------------------------------------------- | | `csv` | yes | Path to the labels CSV inside the ingestor. | | `images` | yes | The `images/` folder. Its parent becomes the dataset root. | | `label` | yes | Name of the class column in the CSV. | | `target_size` | no | `[width, height]` every image must have. Default `[256, 256]`. | | `spec.file_options.extension` | no | `.jpg`, `.jpeg` or `.png`. Default `.jpeg`. | | `spec.file_options.min_size` | no | Absolute minimum `[width, height]`; images with a smaller side are rejected. Default `[32, 32]`. | | `color_mode`, `bit_depth` | no | Declare `RGB` or `grayscale` and `8` or `16` so combined datasets can be checked for consistency. | To use images of another size, set `target_size` (or `spec.file_options.target_size`) to their exact dimensions: ```yaml theme={null} target_size: [512, 512] spec: file_options: extension: .png ``` ## What the ingestor checks | Check | Rejects | | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | File type | Any file under `images/` whose extension is not the configured one, or a mix of extensions. | | Image resolution | Any image whose `(width, height)` differs from `target_size`, more than one resolution in the folder, images with a side below `min_size`, and unreadable or empty image files. | | Label column | A CSV whose header has no column matching `label:`. | | Label diversity | Fewer than two distinct label values. | Plus the [checks every ingest runs](/create-use-case/templates#checks-every-ingest-runs). ## Sample dataset The template ships six 256×256 RGB JPEG images (three cats, three dogs) and a labels CSV with the two classes `cat` and `dog`. The `ingest.yaml` above ingests it with no overrides. ## Next steps * Stage the data and run the ingest: [Prepare Data](/create-use-case/prepare-dataset) * Shared rules for every template: [Dataset templates](/create-use-case/templates) # Keypoint detection Source: https://docs.tracebloc.io/create-use-case/templates/keypoint-detection Dataset template for keypoint detection: images plus per-image keypoint JSON in the labels CSV, ingest.yaml and the checks the data ingestor runs. Locate landmark points, for example body joints. Each sample is one image plus one CSV row that carries the keypoint coordinates, their visibility flags and a class label. ## Folder layout ```text theme={null} /data/shared/pose/ ├── labels.csv └── images/ ├── person_001.jpg ├── person_002.jpg └── ... ``` * The image folder must be named `images` and sit next to the labels CSV. * All images share one extension (`.jpg`, `.jpeg` or `.png`; default `.jpg`) and one resolution, which you declare in `target_size`. The ingestor copies them unchanged. ## Labels CSV ```csv theme={null} filename,Annotation,Visibility,image_label person_001,"{""nose"": [0.50, 0.20], ""left_eye"": [0.46, 0.16], ""right_eye"": [0.54, 0.16], ""left_shoulder"": [0.37, 0.39], ""right_shoulder"": [0.63, 0.39], ""left_elbow"": [0.31, 0.59], ""right_elbow"": [0.68, 0.59], ""left_wrist"": [0.27, 0.76], ""right_wrist"": [0.72, 0.76]}","{""nose"": 1, ""left_eye"": 1, ""right_eye"": 1, ""left_shoulder"": 1, ""right_shoulder"": 1, ""left_elbow"": 1, ""right_elbow"": 1, ""left_wrist"": 1, ""right_wrist"": 1}",person ``` | Column | Required | Meaning | | ------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `filename` | yes, exactly this name | The image file, with or without extension. | | `Annotation` | yes, exactly this name | A JSON object mapping each keypoint name to `[x, y]` (a `{"x": .., "y": ..}` object is also accepted). Quote the JSON and double the inner quotes, as in the sample. | | `Visibility` | yes, exactly this name | A JSON object with the **same keys** as `Annotation`, each `1` (visible) or `0` (occluded or out of frame). | | `image_label` | yes | The class of the image. Any column name works — set it with `label:`. At least two distinct classes are required. | Rules for `Annotation`: * Every row must name exactly `number_of_keypoints` keypoints, and every row must use the same keypoint names as the first row. * Coordinates must be numeric and non-negative, with `x < width` and `y < height` of `target_size`. * At least two keypoints must differ in both x and y, so the keypoints span a real bounding box. ## ingest.yaml ```yaml theme={null} apiVersion: tracebloc.io/v1 kind: IngestConfig category: keypoint_detection table: pose_train intent: train csv: /data/shared/pose/labels.csv images: /data/shared/pose/images/ label: image_label target_size: [448, 448] # width, height — must match your images number_of_keypoints: 9 # 17 for COCO pose; 9 for the shipped sample ``` | Field | Required | Meaning | | ----------------------------- | -------- | ---------------------------------------------------------------------------------------------- | | `csv` | yes | Path to the labels CSV. | | `images` | yes | The `images/` folder. | | `label` | yes | Name of the class column. | | `target_size` | **yes** | `[width, height]` of every image. There is no default for this task — your pose model decides. | | `number_of_keypoints` | **yes** | Keypoints per sample. Every row's `Annotation` must have exactly this many entries. | | `spec.file_options.extension` | no | `.jpg`, `.jpeg` or `.png`. Default `.jpg`. | | `spec.file_options.min_size` | no | Minimum `[width, height]`. Default `[32, 32]`. | | `color_mode`, `bit_depth` | no | `RGB` or `grayscale`; `8` or `16`. | ## What the ingestor checks | Check | Rejects | | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | File type | Files under `images/` with a different extension than configured, or mixed extensions. | | Image resolution | Images whose size differs from `target_size`, mixed resolutions, images below `min_size`, unreadable files. | | Keypoint annotation | A missing `Annotation` column; invalid JSON; a row with a keypoint count other than `number_of_keypoints`; keypoint names that differ between rows; non-numeric, negative or out-of-image coordinates; a degenerate bounding box. | | Keypoint visibility | A missing `Visibility` column; invalid JSON; values other than `0`/`1`; keys that do not match the row's `Annotation` keys. | | Label diversity | Fewer than two distinct label values. | Plus the [checks every ingest runs](/create-use-case/templates#checks-every-ingest-runs). ## Sample dataset The template ships three 448×448 RGB JPEG images with nine upper-body keypoints each (`nose`, `left_eye`, `right_eye`, `left_shoulder`, `right_shoulder`, `left_elbow`, `right_elbow`, `left_wrist`, `right_wrist`) and three classes. The `ingest.yaml` above ingests it as is. ## Next steps * Stage the data and run the ingest: [Prepare Data](/create-use-case/prepare-dataset) * Shared rules for every template: [Dataset templates](/create-use-case/templates) # Masked language modeling Source: https://docs.tracebloc.io/create-use-case/templates/masked-language-modeling Dataset template for masked language modeling: one token sequence per .txt under sequences/, a manifest CSV without labels, ingest.yaml and the checks the data ingestor runs. Predict masked-out words. This task is **self-supervised**: there is no label — the training side masks tokens on the fly. Each sample is one `.txt` file holding a space-separated token sequence, listed in a manifest CSV. ## Folder layout ```text theme={null} /data/shared/primekg-mlm/ ├── labels.csv └── sequences/ ├── seq_0000001.txt ├── seq_0000002.txt └── ... ``` * The folder is named `sequences` (not `texts`) — the ingestor reserves `sequences/` for pre-tokenized data — and sits next to the manifest CSV. * One sequence per file, tokens separated by spaces, UTF-8 encoded, one extension across the dataset (`.txt` by default). Example from the shipped sample: `Lepirudin indication Huntington phenotype_present Chorea associated_with Dystonia`. * The shipped sample also contains a `tokenizer.json` next to the CSV. The current ingestor neither reads nor copies it; it is part of the sample only. ## Manifest CSV ```csv theme={null} filename seq_0000001 seq_0000002 seq_0000003 ``` | Column | Required | Meaning | | ----------- | ---------------------- | ------------------------------------------------------------------- | | `filename` | yes, exactly this name | The sequence file, with or without extension. | | `extension` | no | Present in the shipped sample (`'.txt'`); not read by the ingestor. | There is no label column. Setting `label:` in `ingest.yaml` is rejected. ## ingest.yaml ```yaml theme={null} apiVersion: tracebloc.io/v1 kind: IngestConfig category: masked_language_modeling table: primekg_mlm_train intent: train csv: /data/shared/primekg-mlm/labels.csv sequences: /data/shared/primekg-mlm/sequences/ ``` | Field | Required | Meaning | | ----------------------------- | ------------------- | ------------------------------------------------------------- | | `csv` | yes | Path to the manifest CSV. | | `sequences` | yes | The `sequences/` folder. Its parent becomes the dataset root. | | `label` | **must not be set** | Self-supervised task. | | `schema` | no | Extra typed columns only. Never `filename`. | | `spec.file_options.extension` | no | `.txt` (default) or `.text`. | | `language`, `normalization` | no | Dataset language and applied normalization. | ## What the ingestor checks | Check | Rejects | | ------------ | ----------------------------------------------------------------------------------------- | | File type | Files under `sequences/` with a different extension than configured, or mixed extensions. | | Text content | NUL bytes or invalid UTF-8; empty files produce a warning. | | Data types | With a `schema`: values that do not match their declared type. | Plus the [checks every ingest runs](/create-use-case/templates#checks-every-ingest-runs), except label diversity (no label). For text tasks the ingestor also records a data-derived text profile — Unicode-script mix and document-length distribution, never the text itself — so the platform can warn when a model's tokenizer is a poor fit for the dataset. ## Sample dataset The template ships five knowledge-graph random-walk sequences and a five-row manifest. The `ingest.yaml` above ingests it with no overrides. ## Next steps * Stage the data and run the ingest: [Prepare Data](/create-use-case/prepare-dataset) * Shared rules for every template: [Dataset templates](/create-use-case/templates) # Object detection Source: https://docs.tracebloc.io/create-use-case/templates/object-detection Dataset template for object detection: images plus Pascal VOC XML annotations, ingest.yaml and the checks the data ingestor runs. Draw boxes around objects. Each sample is one image plus one Pascal VOC XML file that lists the objects in it. There is **no labels CSV**: the ingestor reads the image list and the classes straight from the XML files. ## Folder layout ```text theme={null} /data/shared/visdrone/ ├── images/ │ ├── 0000001_02999_d_0000005.jpg │ └── ... └── annotations/ ├── 0000001_02999_d_0000005.xml └── ... ``` * Both folders must have exactly these names and sit side by side. * Images and annotations pair by **file stem**: `images/frame01.jpg` belongs to `annotations/frame01.xml`. Every image needs its XML and every XML needs its image. * All images share one extension (`.jpg`, `.jpeg` or `.png`; default `.jpg`) and one resolution. The ingestor copies them unchanged and does not resize. ## Annotation format (Pascal VOC) ```xml theme={null} images frame01.jpg Unknown PASCAL VOC 1920 1080 3 0 car Unspecified 0 0 871 572 925 664 ``` Every element shown is required: | Element | Rule | | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `folder`, `filename` | Non-empty text. | | `source/database`, `source/annotation` | Non-empty text. | | `size/width`, `size/height`, `size/depth` | Positive integers. `width` and `height` must equal the actual image dimensions. | | `segmented` | `0` or `1`. | | `object/name` | The class. Non-empty. | | `object/pose` | Non-empty text (`Unspecified` is fine). | | `object/truncated` | `0` or `1`. | | `object/difficult` | A non-negative integer. Values other than `0`/`1` are accepted with a warning. | | `object/bndbox` | Integer `xmin`, `ymin`, `xmax`, `ymax` with `xmin < xmax`, `ymin < ymax`, all non-negative, and `xmax`/`ymax` within the declared image size. A box with area below 10 pixels produces a warning. | An XML file with no `` is accepted with a warning. ## ingest.yaml ```yaml theme={null} apiVersion: tracebloc.io/v1 kind: IngestConfig category: object_detection table: visdrone_train intent: train images: /data/shared/visdrone/images/ annotations: /data/shared/visdrone/annotations/ ``` | Field | Required | Meaning | | ----------------------------- | ------------------- | ---------------------------------------------------------------------------------------------------------------------------- | | `images` | yes | The `images/` folder. | | `annotations` | yes | The `annotations/` folder. The record list comes from here. | | `csv`, `json` | **must not be set** | Object detection has no manifest; the config is rejected if either is present. | | `label` | leave out | Classes come from `object/name`. | | `target_size` | no | `[width, height]` every image must have. Default `[1920, 1080]`. Set it to your images' real size, for example `[448, 448]`. | | `spec.file_options.extension` | no | `.jpg`, `.jpeg` or `.png`. Default `.jpg`. | | `spec.file_options.min_size` | no | Minimum `[width, height]`. Default `[32, 32]`. | | `color_mode`, `bit_depth` | no | `RGB` or `grayscale`; `8` or `16`. | ## How records are stored One record per **image**, not per box. The stored label of an image is its class histogram (for example `car:3 motor:1`), so the dataset summary reports class counts in boxes while the record count is the number of images. Data ids are content hashes, so re-running a failed ingest re-uses its rows. ## What the ingestor checks | Check | Rejects | | ----------------------- | ----------------------------------------------------------------------------------------------------------- | | File type (images) | Files under `images/` with an extension other than the configured one, or mixed extensions. | | File type (annotations) | Files under `annotations/` that are not `.xml`. | | Pascal VOC XML | Any XML that breaks the rules in the table above. | | File pairing | Images without a matching `.xml`, and XML files without a matching image. | | Image resolution | Images whose size differs from `target_size`, mixed resolutions, images below `min_size`, unreadable files. | | Label diversity | Fewer than two distinct classes across all `object/name` values. | Plus the [checks every ingest runs](/create-use-case/templates#checks-every-ingest-runs). A record is copied only when both its image and its XML copy succeed. ## Sample dataset The template ships one 1920×1080 aerial traffic frame from the public VisDrone dataset with its VOC annotation (classes such as `car` and `motor`). The `ingest.yaml` above ingests it with no overrides. ## Next steps * Stage the data and run the ingest: [Prepare Data](/create-use-case/prepare-dataset) * Shared rules for every template: [Dataset templates](/create-use-case/templates) # Semantic segmentation Source: https://docs.tracebloc.io/create-use-case/templates/semantic-segmentation Dataset template for semantic segmentation: images plus PNG masks linked by mask_id, ingest.yaml and the checks the data ingestor runs. Label every pixel. Each sample is one image, one mask image of the same size whose pixel values are class indices, and one CSV row that links the two and names a class present in the image. ## Folder layout ```text theme={null} /data/shared/tumors/ ├── labels.csv ├── images/ │ ├── image_001.jpg │ ├── image_002.jpg │ └── ... └── masks/ ├── image_001_mask.png ├── image_002_mask.png └── ... ``` * The folders must be named `images` and `masks` and sit side by side, next to the labels CSV. * Masks are **PNG** files named `_mask.png`. Every image needs a mask and every mask needs an image. * Masks must be readable images with exactly the same width and height as the images. The template's masks are single-channel (grayscale) PNGs where pixel value `0` is background and `1`, `2`, ... are classes. * Images share one extension (`.jpg`, `.jpeg` or `.png`; default `.jpg`) and one resolution. Nothing is resized at ingest. ## Labels CSV ```csv theme={null} filename,mask_id,image_label image_001,image_001_mask,road image_002,image_002_mask,building image_003,image_003_mask,person ``` | Column | Required | Meaning | | ------------- | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `filename` | yes, exactly this name | The image file, with or without extension. | | `mask_id` | yes, exactly this name, lowercase | The mask file name, with or without extension (`image_001_mask` resolves to `masks/image_001_mask.png`). Must be populated on every row and declared in `schema` — training reads this column to find each mask. | | `image_label` | yes | A class present in the image. Any column name works — set it with `label:`. At least two distinct values are required across the dataset. | An image may appear on several rows, one per class it contains. ## ingest.yaml ```yaml theme={null} apiVersion: tracebloc.io/v1 kind: IngestConfig category: semantic_segmentation table: tumors_train intent: train csv: /data/shared/tumors/labels.csv images: /data/shared/tumors/images/ masks: /data/shared/tumors/masks/ label: image_label schema: mask_id: VARCHAR(255) # required — the training side reads this column to locate each mask ``` | Field | Required | Meaning | | ----------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------- | | `csv` | yes | Path to the labels CSV. | | `images` | yes | The `images/` folder. | | `masks` | yes | The `masks/` folder. | | `label` | yes | Name of the class column. | | `schema` | **yes** | Must declare `mask_id` (exactly that spelling). Without it the column is not stored and training cannot find the masks. | | `target_size` | no | `[width, height]` of every image and every mask. Default `[512, 512]`. | | `spec.file_options.extension` | no | Image extension: `.jpg`, `.jpeg` or `.png`. Default `.jpg`. Masks are always checked as `.png`. | | `spec.file_options.min_size` | no | Minimum `[width, height]`. Default `[32, 32]`. | | `color_mode`, `bit_depth` | no | `RGB` or `grayscale`; `8` or `16`. | ## What the ingestor checks | Check | Rejects | | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | File type (images) | Files under `images/` with an extension other than the configured one, or mixed extensions. | | File type (masks) | Files under `masks/` that are not `.png`. | | File pairing | Images without a `_mask.png`, and masks without a matching image (or not following the `_mask` naming). | | Mask id column | A `schema` without `mask_id`; a manifest without a `mask_id` header; any row whose `mask_id` is empty or a null token. A wrong-case variant (`Mask_ID`) is reported with a rename hint. | | Image resolution | Images whose size differs from `target_size`, mixed resolutions, images below `min_size`, unreadable files. | | Mask resolution | The same rule applied to `masks/`. | | Label diversity | Fewer than two distinct label values. | Plus the [checks every ingest runs](/create-use-case/templates#checks-every-ingest-runs). A record is copied only when both its image and its mask copy succeed. ## Sample dataset The template ships three 512×512 RGB JPEG images, three matching single-channel PNG masks and a three-row labels CSV (`road`, `building`, `person`). The `ingest.yaml` above ingests it with no overrides. ## Next steps * Stage the data and run the ingest: [Prepare Data](/create-use-case/prepare-dataset) * Shared rules for every template: [Dataset templates](/create-use-case/templates) # Sentence-pair classification Source: https://docs.tracebloc.io/create-use-case/templates/sentence-pair-classification Dataset template for sentence-pair classification: one tab-separated sentence pair per .txt plus a labels CSV, ingest.yaml and the checks the data ingestor runs. Label how two texts relate — entailment, paraphrase, duplicate question. Each sample is one `.txt` file holding **two sentences separated by a single tab**, plus one CSV row with the class label. ## Folder layout ```text theme={null} /data/shared/mnli-pairs/ ├── labels.csv └── texts/ ├── pair1.txt ├── pair2.txt └── ... ``` Each file is exactly one line of the form `text_atext_b`, for example: ```text theme={null} A man is playing a guitar. A person is making music. ``` * The folder must be named `texts` and sit next to the labels CSV. * Exactly two non-empty fields separated by one tab, on one line. Plain prose without a tab, an empty side, or several pairs in one file are rejected. * UTF-8 encoded; one extension across the dataset (`.txt` by default). ## Labels CSV ```csv theme={null} filename,label pair1,entailment pair2,contradiction pair3,neutral ``` | Column | Required | Meaning | | ----------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------- | | `filename` | yes, exactly this name | The text file, with or without extension. | | `label` | yes | The class of the pair. Any column name works — set it with `label:`. At least two distinct classes are required. | | `extension` | no | Present in the shipped sample; not read by the ingestor. | Do not declare `filename` or `label` in `schema`. ## ingest.yaml ```yaml theme={null} apiVersion: tracebloc.io/v1 kind: IngestConfig category: sentence_pair_classification table: mnli_sentence_pairs_train intent: train csv: /data/shared/mnli-pairs/labels.csv texts: /data/shared/mnli-pairs/texts/ label: label ``` | Field | Required | Meaning | | ----------------------------- | -------- | ------------------------------------------- | | `csv` | yes | Path to the labels CSV. | | `texts` | yes | The `texts/` folder. | | `label` | yes | Name of the class column. | | `schema` | no | Extra typed columns only. | | `spec.file_options.extension` | no | `.txt` (default) or `.text`. | | `language`, `normalization` | no | Dataset language and applied normalization. | ## What the ingestor checks | Check | Rejects | | --------------- | -------------------------------------------------------------------------------------------------------------- | | File type | Files under `texts/` with a different extension than configured, or mixed extensions. | | Text content | NUL bytes or invalid UTF-8; empty files produce a warning. | | Sentence pair | A referenced file that is missing, spans several lines, has a field count other than 2, or has an empty field. | | Label column | A CSV whose header has no column matching `label:`. | | Data types | With a `schema`: values that do not match their declared type. | | Label diversity | Fewer than two distinct label values. | Plus the [checks every ingest runs](/create-use-case/templates#checks-every-ingest-runs). ## Sample dataset The template ships five sentence pairs labelled `entailment`, `contradiction` and `neutral`. The `ingest.yaml` above ingests it with no overrides. ## Next steps * Stage the data and run the ingest: [Prepare Data](/create-use-case/prepare-dataset) * Shared rules for every template: [Dataset templates](/create-use-case/templates) # Sequence-to-sequence Source: https://docs.tracebloc.io/create-use-case/templates/seq2seq Dataset template for sequence-to-sequence tasks (translation, summarization): one source/target pair per .txt, a manifest CSV without labels, ingest.yaml and the checks the data ingestor runs. Map an input sequence to an output sequence — translation, summarization, paraphrase. This task is **self-supervised** from the ingestor's point of view: there is no label column, because the target side of each pair is the supervision. Each sample is one `.txt` file with one line of the form `sourcetarget`. ## Folder layout ```text theme={null} /data/shared/wmt-seq2seq/ ├── labels.csv └── texts/ ├── s2s_0000001.txt ├── s2s_0000002.txt └── ... ``` Each file holds one pair, for example: ```text theme={null} Translate to French: Good morning. Bonjour. ``` * The folder is named `texts` and sits next to the manifest CSV. * Put exactly one tab between source and target: everything before the first tab is the source, everything after is the target. The ingestor does not enforce this structure — it only checks that files are valid text — so a malformed file surfaces at training time, not at ingest. * UTF-8 encoded; one extension across the dataset (`.txt` by default). ## Manifest CSV ```csv theme={null} filename s2s_0000001 s2s_0000002 s2s_0000003 ``` | Column | Required | Meaning | | ----------- | ---------------------- | ------------------------------------------------------------------- | | `filename` | yes, exactly this name | The text file, with or without extension. | | `extension` | no | Present in the shipped sample (`'.txt'`); not read by the ingestor. | There is no label column. Setting `label:` in `ingest.yaml` is rejected. ## ingest.yaml ```yaml theme={null} apiVersion: tracebloc.io/v1 kind: IngestConfig category: seq2seq table: wmt_seq2seq_train intent: train csv: /data/shared/wmt-seq2seq/labels.csv texts: /data/shared/wmt-seq2seq/texts/ ``` | Field | Required | Meaning | | ----------------------------- | ------------------- | ------------------------------------------- | | `csv` | yes | Path to the manifest CSV. | | `texts` | yes | The `texts/` folder. | | `label` | **must not be set** | No label column. | | `schema` | no | Extra typed columns only. Never `filename`. | | `spec.file_options.extension` | no | `.txt` (default) or `.text`. | | `language`, `normalization` | no | Dataset language and applied normalization. | ## What the ingestor checks | Check | Rejects | | ------------ | ------------------------------------------------------------------------------------- | | File type | Files under `texts/` with a different extension than configured, or mixed extensions. | | Text content | NUL bytes or invalid UTF-8; empty files produce a warning. | | Data types | With a `schema`: values that do not match their declared type. | Plus the [checks every ingest runs](/create-use-case/templates#checks-every-ingest-runs), except label diversity (no label). ## Sample dataset The template ships five `sourcetarget` pairs (translation, summarization and paraphrase examples) with a five-row manifest. The `ingest.yaml` above ingests it with no overrides. ## Next steps * Stage the data and run the ingest: [Prepare Data](/create-use-case/prepare-dataset) * Shared rules for every template: [Dataset templates](/create-use-case/templates) # Tabular classification Source: https://docs.tracebloc.io/create-use-case/templates/tabular-classification Dataset template for tabular classification: one CSV with features and a class column, the typed schema, ingest.yaml and the checks the data ingestor runs. Predict a class from table columns. The dataset is a single CSV with a header row: feature columns plus one class column. There are no per-sample files. ## Folder layout ```text theme={null} /data/shared/churn/ └── customers.csv ``` * One CSV, UTF-8, comma-separated, with a header row. * Every column has one consistent type. Feature columns are typically numeric; the class column may be text or integer codes. ## Data CSV ```csv theme={null} id,feature_00,feature_01,feature_02,label 1,1.6680773978214032,-0.903902455,6.661496229171176,0 2,0.7017820066004041,1.9789541930566035,5.826137181850707,0 4,4.427524335645055,-1.543700586,6.2987092866052485,1 ``` | Column | Meaning | | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | feature columns | Declared in `schema` with their SQL type and stored as table columns. A column that is not in `schema` is not stored. | | class column (`label` here) | Named by `label:`; **not** declared in `schema`. At least two distinct values are required. | | `id` | Optional in your CSV, but it cannot be declared in `schema` (`id` is reserved). To use it as the row id, set `data_id: {strategy: column, column: id}` — only if it carries no personal data. | In `schema` columns, empty cells and exactly the tokens `NA`, `N/A`, `n/a`, `NULL`, `null`, `None`, `none`, `NaN`, `nan`, ``, `#N/A` (case-sensitive) are stored as NULL. ## ingest.yaml ```yaml theme={null} apiVersion: tracebloc.io/v1 kind: IngestConfig category: tabular_classification table: churn_train intent: train csv: /data/shared/churn/customers.csv schema: feature_00: FLOAT feature_01: FLOAT feature_02: FLOAT label: label ``` | Field | Required | Meaning | | ------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `csv` | yes | Path to the data CSV. | | `schema` | **yes** | Column name to SQL type for every feature column you want stored. Every schema column must exist in the CSV header. See [SQL types](/create-use-case/templates#sql-types-for-schema). | | `label` | yes | Name of the class column. String shorthand is fine; the value is sent to the platform as is. | | `columns` | no | Per-column `unit` and `ordinal` facts for consistency checks across combined datasets. | | `data_id` | no | Row id strategy; see [the contract](/create-use-case/templates#the-ingestyaml-contract). | | `spec.csv_options` | no | `delimiter`, `quotechar`, `escapechar`, `chunk_size`. | ## What the ingestor checks | Check | Rejects | | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Data types | Duplicate header names; a schema column missing from the CSV; any value that does not fit its declared type (non-numeric in `INT`/`FLOAT`, over-long `VARCHAR`, `inf`, out-of-range integers, unparseable dates); unknown SQL type names. The whole file is scanned. | | Label diversity | Fewer than two distinct label values (after whitespace stripping). | Plus the [checks every ingest runs](/create-use-case/templates#checks-every-ingest-runs). ## Sample dataset The template ships a synthetic CSV with `id`, three `FLOAT` features (`feature_00`, `feature_01`, `feature_02`) and a binary `label` column — the rows shown above are its first rows. The `ingest.yaml` above ingests it as is; only `csv:` changes to wherever you staged the file. ## Next steps * Stage the data and run the ingest: [Prepare Data](/create-use-case/prepare-dataset) * Shared rules for every template: [Dataset templates](/create-use-case/templates) # Tabular regression Source: https://docs.tracebloc.io/create-use-case/templates/tabular-regression Dataset template for tabular regression: one CSV with features and a numeric target, the typed schema, the required label policy, ingest.yaml and the checks the data ingestor runs. Predict a number from table columns. The dataset is a single CSV with a header row: feature columns plus one numeric target column. Because the target is a raw numeric value, the `label` must declare a **policy** that keeps raw targets inside your secure environment. ## Folder layout ```text theme={null} /data/shared/house-prices/ └── houses.csv ``` * One CSV, UTF-8, comma-separated, with a header row. * Feature columns are numeric or typed text; the target column holds a continuous number. ## Data CSV ```csv theme={null} id,square_feet,bedrooms,age,price 1,1668.08,3,15,285.50 2,1701.78,4,12,320.75 3,1697.01,2,8,245.30 ``` | Column | Meaning | | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------- | | feature columns | Declared in `schema` with their SQL type and stored. | | target column (`price` here) | Named by `label.column`; **not** declared in `schema`. | | `id` | Optional; cannot be declared in `schema` (reserved). Use `data_id: {strategy: column, column: id}` to keep it as the row id. | ## ingest.yaml ```yaml theme={null} apiVersion: tracebloc.io/v1 kind: IngestConfig category: tabular_regression table: house_prices_train intent: train csv: /data/shared/house-prices/houses.csv schema: square_feet: FLOAT bedrooms: INT age: INT label: column: price policy: bucket ``` | Field | Required | Meaning | | ----------------------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `csv` | yes | Path to the data CSV. | | `schema` | **yes** | Column name to SQL type for the feature columns. Every schema column must exist in the CSV. | | `label` | **yes, object form** | `column` names the target; `policy` is required. `bucket` sends the platform one of 64 stable hash buckets per value instead of the raw number — the stored rows keep the raw target for training. `passthrough` sends raw values; use it only with a compliance sign-off. | | `columns` | no | Per-column `unit` (for example `USD`) and `ordinal` facts. | | `data_id`, `spec.csv_options` | no | See [the contract](/create-use-case/templates#the-ingestyaml-contract). | ## What the ingestor checks | Check | Rejects | | ---------- | ------------------------------------------------------------------------------------------------------------------------------- | | Data types | Duplicate header names; a schema column missing from the CSV; any value that does not fit its declared type; unknown SQL types. | Plus the [checks every ingest runs](/create-use-case/templates#checks-every-ingest-runs). There is no label-diversity check: a continuous target has no classes. ## Sample dataset The template ships a synthetic housing CSV with `id`, `square_feet` (`FLOAT`), `bedrooms` (`INT`), `age` (`INT`) and the target `price` — the rows shown above are its first rows. The `ingest.yaml` above ingests it as is; only `csv:` changes to wherever you staged the file. ## Next steps * Stage the data and run the ingest: [Prepare Data](/create-use-case/prepare-dataset) * Shared rules for every template: [Dataset templates](/create-use-case/templates) # Text classification Source: https://docs.tracebloc.io/create-use-case/templates/text-classification Dataset template for text classification: one .txt per sample plus a labels CSV, ingest.yaml and the checks the data ingestor runs. Sort texts into classes. Each sample is one `.txt` file plus one row in a labels CSV that names the file and its class. ## Folder layout ```text theme={null} /data/shared/tickets/ ├── labels.csv └── texts/ ├── sample1.txt ├── sample2.txt └── ... ``` * The text folder must be named `texts` and sit next to the labels CSV. * One document per file, UTF-8 encoded. All files share one extension: `.txt` (default) or `.text`. ## Labels CSV ```csv theme={null} filename,label sample1,positive sample2,negative sample3,neutral ``` | Column | Required | Meaning | | ----------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | | `filename` | yes, exactly this name | The text file, with or without extension (`sample1` resolves to `texts/sample1.txt`). | | `label` | yes | The class. Any column name works — set it with `label:`. At least two distinct classes are required. | | `extension` | no | The shipped sample carries an `extension` column (`'.txt'`). The ingestor does not read it; the stored extension is always the configured one. | Do not declare `filename` in `schema` — it is a reserved column and a `schema` entry for it fails the ingest. The label column does not need to be in `schema` either: `label:` names it, and the ingestor removes it from the stored table schema if you declare it anyway. `schema` is only for additional typed columns you want stored alongside each sample. ## ingest.yaml ```yaml theme={null} apiVersion: tracebloc.io/v1 kind: IngestConfig category: text_classification table: support_tickets_train intent: train csv: /data/shared/tickets/labels.csv texts: /data/shared/tickets/texts/ label: label ``` | Field | Required | Meaning | | ----------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `csv` | yes | Path to the labels CSV. | | `texts` | yes | The `texts/` folder. Its parent becomes the dataset root. | | `label` | yes | Name of the class column. | | `schema` | no | Extra columns to type-check and store, for example `source: VARCHAR(64)`. Never `filename`; the label column is named by `label:` instead. | | `spec.file_options.extension` | no | `.txt` (default) or `.text`. | | `language`, `normalization` | no | The dataset language (for example `en`) and any normalization applied (for example `lowercase`), recorded for consistency checks when datasets are combined. | ## What the ingestor checks | Check | Rejects | | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | | File type | Files under `texts/` with an extension other than the configured one, or mixed extensions. | | Text content | Files containing a NUL byte or bytes that are not valid UTF-8 (a sample of up to 500 files, first 64 KB each). Empty or whitespace-only files produce a warning. | | Label column | A CSV whose header has no column matching `label:`. | | Data types | With a `schema`: values that do not match their declared type. | | Label diversity | Fewer than two distinct label values. | Plus the [checks every ingest runs](/create-use-case/templates#checks-every-ingest-runs). ## Sample dataset The template ships five product-review style `.txt` files and a labels CSV with the classes `positive`, `negative` and `neutral`. The `ingest.yaml` above ingests it with no overrides. ## Next steps * Stage the data and run the ingest: [Prepare Data](/create-use-case/prepare-dataset) * Shared rules for every template: [Dataset templates](/create-use-case/templates) # Time-series classification Source: https://docs.tracebloc.io/create-use-case/templates/time-series-classification Dataset template for time-series classification: one CSV of time-step rows grouped by sequence_id with one label per sequence, ingest.yaml and the checks the data ingestor runs. Predict a class for a whole sequence — for example one outcome per patient stay, device or session from its multivariate time series. The dataset is a single CSV with **one row per time step**; the rows of one sequence share a `sequence_id` and are ordered by `timestamp` within that sequence. The label is per sequence and repeats on every row of it. ## Folder layout ```text theme={null} /data/shared/icu-sepsis/ └── vitals.csv ``` ## Data CSV ```csv theme={null} sequence_id,timestamp,heart_rate,resp_rate,temperature,spo2,lactate,label patient_001,2024-03-10 08:00:00,69.0,25.3,36.1,94.8,3.43,1 patient_001,2024-03-10 09:00:00,71.6,25.6,38.6,95.0,,1 patient_001,2024-03-10 10:00:00,78.1,20.6,39.1,90.3,3.53,1 patient_002,2024-03-11 08:00:00,105.9,19.0,37.1,98.5,2.47,0 patient_002,2024-03-11 09:00:00,80.7,16.3,37.4,90.3,,0 ``` | Column | Meaning | | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `sequence_id` | **Fixed name.** The entity whose rows form one sequence (patient, device, session). Declared in `schema` as `VARCHAR`; no row may leave it empty. | | `timestamp` | **Fixed name.** Orders the rows within a sequence. Declared in `schema` either as a calendar type (`TIMESTAMP`, `DATETIME`, `DATE` — use ISO 8601 values) or as a numeric step index (`INT`, `FLOAT`, ...). Must be non-decreasing within each sequence; sequences may be interleaved. No missing values. | | feature columns | Numeric, declared in `schema`. Empty cells are allowed (a lab value not measured at every step). | | label column (`label` here) | Named by `label:`, not declared in `schema`. **Constant within each sequence.** At least two distinct values across the dataset. | Sequences may have different lengths. Keep each sequence complete within one ingest — the dataset summary counts sequences, not rows, and a sequence split across two ingests is counted twice. ## ingest.yaml ```yaml theme={null} apiVersion: tracebloc.io/v1 kind: IngestConfig category: time_series_classification table: icu_vitals_sepsis_train intent: train csv: /data/shared/icu-sepsis/vitals.csv schema: sequence_id: VARCHAR(64) # group key — fixed name timestamp: TIMESTAMP # order key within a sequence — fixed name; INT for a step index heart_rate: FLOAT resp_rate: FLOAT temperature: FLOAT spo2: FLOAT lactate: FLOAT # blank cells allowed label: label ``` | Field | Required | Meaning | | ----------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | `csv` | yes | Path to the data CSV. | | `schema` | **yes** | Must declare both `sequence_id` and `timestamp`, plus the numeric feature columns. A non-text type for `sequence_id` is accepted with a warning. | | `label` | yes | Name of the per-sequence outcome column. String shorthand — this is a classification task. | | `time_column` | leave out | The order column is always `timestamp`; any other value is rejected at preflight. | | `data_id` | no | Must **not** use `strategy: column` with `column: sequence_id` — row ids are unique per row, so every sequence would collapse to one row. | | `columns`, `spec.csv_options` | no | See [the contract](/create-use-case/templates#the-ingestyaml-contract). | ## What the ingestor checks | Check | Rejects | | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Sequence group | A CSV without `sequence_id`; rows with an empty `sequence_id`; a `data_id` column strategy pointed at `sequence_id`. | | Label constant within group | Any sequence whose label value changes between its rows (including a mix of a value and empty cells). | | Per-group time ordered | A missing or unparseable `timestamp` on any row; rows within a sequence that are not sorted ascending by `timestamp`; day-first/month-first ambiguous dates when `timestamp` is a calendar type. | | Numeric columns | A non-numeric value in any schema column other than `sequence_id` and `timestamp`. Empty cells are allowed. | | Data types | Duplicate headers, schema columns missing from the CSV, values that do not match their type (every schema column except `timestamp`). | | Label diversity | Fewer than two distinct label values. | Plus the [checks every ingest runs](/create-use-case/templates#checks-every-ingest-runs). After the rows are stored, an integrity pass removes any sequence that lost rows to a failed insert, so a sequence is stored whole or not at all, and the run then exits with an error. ## Sample dataset The template ships 30 hourly rows of synthetic ICU vitals for six sequences (3 to 7 steps each) with five `FLOAT` features (`heart_rate`, `resp_rate`, `temperature`, `spo2`, `lactate` — the last with legal blanks) and a binary per-sequence `label` — the rows shown above are its first rows. The `ingest.yaml` above ingests it as is; only `csv:` changes to wherever you staged the file. ## Next steps * Stage the data and run the ingest: [Prepare Data](/create-use-case/prepare-dataset) * Shared rules for every template: [Dataset templates](/create-use-case/templates) # Time-series forecasting Source: https://docs.tracebloc.io/create-use-case/templates/time-series-forecasting Dataset template for time-series forecasting: one time-ordered CSV with a timestamp column, numeric features and a numeric target, ingest.yaml and the checks the data ingestor runs. Predict future values from past ones. The dataset is a single CSV where every row is one time step: a `timestamp` column, numeric feature columns and a numeric target. Rows must be in chronological order. ## Folder layout ```text theme={null} /data/shared/energy-demand/ └── demand.csv ``` ## Data CSV ```csv theme={null} timestamp,day_of_week,month,day_of_month,week_of_year,is_weekend,lag_1,moving_avg_7,value 2023-10-01,7,10,1,40,1,,,125.50 2023-10-02,1,10,2,40,0,125.50,,132.30 2023-10-03,2,10,3,40,0,132.30,,128.75 2023-10-07,6,10,7,40,1,152.40,132.75,148.60 ``` | Column | Meaning | | ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `timestamp` | **Fixed name.** One value per row in ISO 8601 (`YYYY-MM-DD` or `YYYY-MM-DD HH:MM:SS`). Rows must be sorted ascending; every value must parse; every value must be before today. Dates that read differently day-first and month-first (such as `03.04.2026`) are rejected — use ISO 8601. | | feature columns | Numeric, declared in `schema`. Empty cells are allowed (stored as NULL) — lag and rolling-window features are typically blank at the start of the series. | | target column (`value` here) | Numeric; named by `label.column`, not declared in `schema`. | Categorical features (region, segment, ...) must be encoded as integers before ingest: every non-timestamp column in `schema` must be numeric. ## ingest.yaml ```yaml theme={null} apiVersion: tracebloc.io/v1 kind: IngestConfig category: time_series_forecasting table: energy_demand_train intent: train csv: /data/shared/energy-demand/demand.csv schema: timestamp: TIMESTAMP # required; TIMESTAMP, DATETIME or DATE day_of_week: INT month: INT day_of_month: INT week_of_year: INT is_weekend: INT lag_1: FLOAT # blank on the first row moving_avg_7: FLOAT # blank until 7 rows of history exist label: column: value policy: bucket ``` | Field | Required | Meaning | | ----------------------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `csv` | yes | Path to the data CSV. | | `schema` | **yes** | Must contain `timestamp` with a calendar type (`TIMESTAMP`, `DATETIME` or `DATE`) plus the numeric feature columns. | | `label` | **yes, object form** | `column` names the target; `policy: bucket` keeps raw targets in your secure environment (the platform receives 64 hash buckets; stored rows keep the raw value). | | `time_column` | leave out | The time column is always `timestamp`. Any other value is rejected at preflight. | | `columns` | no | Per-column `unit` and `ordinal` facts. | | `data_id`, `spec.csv_options` | no | See [the contract](/create-use-case/templates#the-ingestyaml-contract). | ## What the ingestor checks | Check | Rejects | | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Time format | A `schema` without `timestamp`, or with `timestamp` typed as text or a number; a CSV without a `timestamp` column; unparseable values; day-first/month-first ambiguous dates. | | Time ordered | Any pair of consecutive rows whose timestamps decrease. | | Time before today | Any timestamp on or after today's date. | | Numeric columns | A non-numeric value in any schema column other than `timestamp`. Empty cells are allowed. | | Data types | Duplicate headers, schema columns missing from the CSV, values that do not match their type (checked for every schema column except `timestamp`). | Plus the [checks every ingest runs](/create-use-case/templates#checks-every-ingest-runs). There is no label-diversity check. ## Sample dataset The template ships 31 daily rows starting 2023-10-01 with calendar features (`day_of_week`, `month`, `day_of_month`, `week_of_year`, `is_weekend` as `INT`), lag and moving-average features (`lag_1`, `moving_avg_7` as `FLOAT`, blank until enough history exists) and the target `value` — the rows shown above are from it. The `ingest.yaml` above ingests it as is; only `csv:` changes to wherever you staged the file. ## Next steps * Stage the data and run the ingest: [Prepare Data](/create-use-case/prepare-dataset) * Shared rules for every template: [Dataset templates](/create-use-case/templates) # Survival analysis (time-to-event) Source: https://docs.tracebloc.io/create-use-case/templates/time-to-event-prediction Dataset template for survival analysis: one CSV with covariates, a duration column and an event indicator, the required label policy, ingest.yaml and the checks the data ingestor runs. Predict how long until an event happens, allowing for cases where it has not happened yet (censoring). The dataset is a single CSV where every row is one subject: covariate columns, a **duration** column and an **event indicator** column (1 = event observed, 0 = censored). ## Folder layout ```text theme={null} /data/shared/survival/ └── survival.csv ``` ## Data CSV ```csv theme={null} age,anaemia,creatinine_phosphokinase,diabetes,ejection_fraction,high_blood_pressure,platelets,serum_creatinine,serum_sodium,sex,smoking,time,DEATH_EVENT 48,0,315,0,40,1,275841,1.6,131,0,1,225,0 78,0,3964,1,62,0,315081,0.9,135,0,0,5,1 64,0,2656,0,45,0,372021,3.0,142,0,1,13,1 ``` | Column | Meaning | | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | covariate columns | Declared in `schema` with their SQL type. | | duration column (`time` here) | Numeric and non-negative; declared in `schema` like any other column. Its name is `time` unless you set `time_column`. Empty values produce a warning. | | event indicator (`DEATH_EVENT` here) | The label column, named by `label.column` and **not** declared in `schema`. Integer codes; declare which code means event and which means censored with `event_indicator`. | ## ingest.yaml ```yaml theme={null} apiVersion: tracebloc.io/v1 kind: IngestConfig category: time_to_event_prediction table: heart_failure_survival_train intent: train csv: /data/shared/survival/survival.csv time_column: time # the default; set it when your duration column has another name time_unit: days event_indicator: event: 1 censored: 0 schema: age: INT anaemia: INT creatinine_phosphokinase: INT diabetes: INT ejection_fraction: INT high_blood_pressure: INT platelets: FLOAT serum_creatinine: FLOAT serum_sodium: INT sex: INT smoking: INT time: INT # the duration column is declared like any other label: column: DEATH_EVENT policy: bucket ``` | Field | Required | Meaning | | ----------------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `csv` | yes | Path to the data CSV. | | `schema` | **yes** | Covariates plus the duration column, with SQL types. Every schema column must exist in the CSV. | | `label` | **yes, object form** | `column` names the event indicator; `policy` is required. `bucket` makes the platform receive hash buckets, not raw values — stored rows keep the raw indicator that training reads. `passthrough` sends raw values; use it only with a compliance sign-off. | | `time_column` | no | Name of the duration column. Default `time`. Matched exactly as written. | | `time_unit` | no | `days`, `weeks`, `months` or `years`. Recorded so combined datasets are not compared across units. | | `event_indicator` | no | `{event: , censored: }` — the codes used in the label column. Recorded so a flipped convention across combined datasets is caught. | | `columns` | no | Per-column `unit` and `ordinal` facts. | | `data_id`, `spec.csv_options` | no | See [the contract](/create-use-case/templates#the-ingestyaml-contract). | ## What the ingestor checks | Check | Rejects | | ------------- | ----------------------------------------------------------------------------------------------------------------------------------- | | Time to event | A CSV without the duration column (exact name); non-numeric duration values; negative durations. Empty durations produce a warning. | | Data types | Duplicate headers, schema columns missing from the CSV, values that do not match their declared type, unknown SQL types. | Plus the [checks every ingest runs](/create-use-case/templates#checks-every-ingest-runs). There is no label-diversity check. ## Sample dataset The template ships 30 synthetic rows shaped like a heart-failure clinical dataset (no real patients): eleven covariates (`age`, `anaemia`, `creatinine_phosphokinase`, `diabetes`, `ejection_fraction`, `high_blood_pressure`, `platelets`, `serum_creatinine`, `serum_sodium`, `sex`, `smoking`), the duration `time` in days and the event indicator `DEATH_EVENT`. The covariates are linearly independent on purpose — a Cox proportional-hazards fit needs that. The rows shown above are its first rows, and the `ingest.yaml` above ingests it as is; only `csv:` changes to wherever you staged the file. ## Next steps * Stage the data and run the ingest: [Prepare Data](/create-use-case/prepare-dataset) * Shared rules for every template: [Dataset templates](/create-use-case/templates) # Token classification Source: https://docs.tracebloc.io/create-use-case/templates/token-classification Dataset template for token classification (NER, POS): pre-tokenized .txt files plus BIO tag sequences in the labels CSV, ingest.yaml and the checks the data ingestor runs. Label each word in a sequence — named-entity recognition, part-of-speech tagging. The layout is the same as [text classification](/create-use-case/templates/text-classification); the difference is the label: instead of one class it holds the **BIO tag sequence** for the words in the file. ## Folder layout ```text theme={null} /data/shared/ner/ ├── labels.csv └── texts/ ├── sample1.txt ├── sample2.txt └── ... ``` * The text folder must be named `texts` and sit next to the labels CSV. * One pre-tokenized sentence per file: words separated by whitespace. The whitespace-separated words are the tokens that get tagged; the model's own tokenizer handles sub-word splitting at training time. * UTF-8 encoded; one extension across the dataset (`.txt` by default). ## Labels CSV ```csv theme={null} filename,label sample1,B-PER I-PER O O B-ORG sample2,B-LOC O O sample3,B-ORG O B-MISC O ``` With `sample1.txt` containing `John Smith works at Google`. | Column | Required | Meaning | | ----------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | | `filename` | yes, exactly this name | The text file, with or without extension. | | `label` | yes | Space-separated tags, **exactly one per word** in the file. Each tag is `O`, `B-` or `I-` (IOB2). Any column name works — set it with `label:`. | | `extension` | no | Present in the shipped sample; not read by the ingestor. | Do not declare `filename` or `label` in `schema`. ## ingest.yaml ```yaml theme={null} apiVersion: tracebloc.io/v1 kind: IngestConfig category: token_classification table: ner_conll_train intent: train csv: /data/shared/ner/labels.csv texts: /data/shared/ner/texts/ label: label ``` | Field | Required | Meaning | | ----------------------------- | -------- | ------------------------------------------- | | `csv` | yes | Path to the labels CSV. | | `texts` | yes | The `texts/` folder. | | `label` | yes | Name of the tag-sequence column. | | `schema` | no | Extra typed columns only. | | `spec.file_options.extension` | no | `.txt` (default) or `.text`. | | `language`, `normalization` | no | Dataset language and applied normalization. | ## What the ingestor checks | Check | Rejects | | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | File type | Files under `texts/` with a different extension than configured, or mixed extensions. | | Text content | NUL bytes or invalid UTF-8; empty files produce a warning. | | BIO labels | A missing `filename` or label column; a row whose label cell is empty; a tag that is not `O`, `B-` or `I-`; a tag count that differs from the word count of the referenced file; a referenced file that does not exist. An `I-` that is not preceded by `B-` or `I-` of the same type is reported as a warning (legal in IOB1, malformed in IOB2). | | Data types | With a `schema`: values that do not match their declared type. | Plus the [checks every ingest runs](/create-use-case/templates#checks-every-ingest-runs). The dataset's classes are the distinct **tags**, not the distinct tag strings, so a single-class check does not apply here. ## Sample dataset The template ships three pre-tokenized sentences with tags spanning `PER`, `ORG`, `LOC` and `MISC`. The `ingest.yaml` above ingests it with no overrides. ## Next steps * Stage the data and run the ingest: [Prepare Data](/create-use-case/prepare-dataset) * Shared rules for every template: [Dataset templates](/create-use-case/templates) # tracebloc CLI Source: https://docs.tracebloc.io/environment-setup/cli Manage and operate your workspace from the command line — inspect the cluster, ingest and remove datasets, validate configs. The `tracebloc` CLI is how you **manage and operate your workspace and its data** from your own machine: inspect the cluster, ingest datasets, remove them, validate configs — with more verbs on the way. It's the friendly front end to the same ingestion protocol the [Helm ingestor chart](https://github.com/tracebloc/client/tree/main/ingestor) speaks, so it works against any workspace running the `tracebloc/client` chart. You never touch Helm, edit YAML, or run `kubectl cp`. `dataset push` discovers your workspace, stages the files, submits, and streams the job for you. ## Install If you deployed with the [Quick Start](/environment-setup/quickstart) one-liner, the CLI is **already installed**. Otherwise: ```bash theme={null} curl -fsSL https://github.com/tracebloc/cli/releases/latest/download/install.sh | sh ``` ```powershell theme={null} irm https://github.com/tracebloc/cli/releases/latest/download/install.ps1 | iex ``` Binaries are cosign-signed and multi-arch. Pin a version with `--version vX.Y.Z` (or `$env:RELEASE_VERSION` on Windows). Verify: ```bash theme={null} tracebloc version ``` ## Operate your workspace ```bash theme={null} tracebloc cluster info ``` Shows the cluster, namespace, parent release, and ingestor-token state — your first check that the CLI can reach your workspace. If `cluster info` reports *"no parent client release found in namespace default"*, your client runs in another namespace — add `-n `, or set it once with `kubectl config set-context --current --namespace `. Every command below accepts `-n`. ## Manage data **Ingest a dataset** — stage local data into your workspace and run ingestion in one step: ```bash theme={null} tracebloc dataset push ./train.csv \ --category tabular_classification \ --table my_dataset_train \ --intent train \ --label-column label ``` Omit the flags to run **guided** (the CLI prompts you), or add `--dry-run` to preview without submitting. Under the hood it discovers your workspace, validates the schema locally, mints a token, stages the files to the shared volume, submits, and watches the job. It covers 9 task categories: `image_classification`, `object_detection`, `keypoint_detection`, `text_classification`, `masked_language_modeling`, `tabular_classification`, `tabular_regression`, `time_series_forecasting`, `time_to_event_prediction`. **Remove a dataset** — delete its table and staged files: ```bash theme={null} tracebloc dataset rm my_dataset_train ``` ## Validate a config locally ```bash theme={null} tracebloc ingest validate ingest.yaml ``` Checks an `ingest.yaml` against the embedded schema — no cluster required. The declarative form (also accepted by the Helm ingestor chart): ```yaml theme={null} apiVersion: tracebloc.io/v1 kind: IngestConfig category: tabular_classification table: my_dataset_train intent: train csv: /data/shared/my_dataset/train.csv label: label ``` ## Command reference | Command | Does | | ---------------------------------- | --------------------------------------------------------- | | `tracebloc dataset push ` | Stage + ingest a local dataset (guided if you omit flags) | | `tracebloc dataset rm ` | Delete a pushed dataset (table + staged files) | | `tracebloc cluster info` | Cluster, namespace, parent release, and token state | | `tracebloc ingest validate ` | Validate an `ingest.yaml` against the v1 schema, locally | | `tracebloc version` | CLI version, git SHA, and build date | | `tracebloc completion` | Generate shell completion | Add `--help` to any command for the full flag list. For workspace lifecycle (upgrade, stop/start, uninstall), see [Operations](/environment-setup/operations). ## CLI or Helm chart? Both submit to the same ingestion protocol — pick the one that fits your workflow: * **CLI** — local data on your workstation; the everyday choice. Handles staging and submission for you. * **[Helm ingestor chart](https://github.com/tracebloc/client/tree/main/ingestor)** — Kubernetes-native / GitOps, when your data is already staged on the cluster. ## Coming soon Cloud-source ingestion (S3 / GCS / HTTPS) for large datasets, a `dataset list` verb, and `semantic_segmentation` support. # Configuration Source: https://docs.tracebloc.io/environment-setup/configuration Customize your tracebloc workspace — environment variables, cluster management, GPU support, and manual Helm deployment. The installer uses sensible defaults; this page covers what you can change. **Installed with the one-liner?** See [Installer Options](#installer-options), [Cluster Management](#cluster-management), and [GPU Support](#gpu-support). **Deploying into your own cluster with Helm** (EKS, AKS, bare-metal)? Jump to [Manual Deployment](#manual-deployment). ## Installer Options Override defaults by setting environment variables before the install command. Useful for a custom cluster name, extra worker nodes, or a different data directory. | Variable | Default | Description | | ------------------ | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `CLUSTER_NAME` | `tracebloc` | Name of the k3d cluster | | `SERVERS` | `1` | Number of control-plane nodes | | `AGENTS` | `1` | Number of worker nodes | | `K8S_VERSION` | `v1.29.4-k3s1` | k3s image tag | | `HOST_DATA_DIR` | `~/.tracebloc` | Persistent data directory on host — **must be a local disk** (NFS/CIFS/SMB is rejected; the database corrupts on network storage). | | `HOST_DATASET_DIR` | *(unset)* | Optional. Place the large dataset volume on a separate mount (e.g. a network/NFS share); the database + logs stay on `HOST_DATA_DIR`. Must already exist and be writable. | Example — custom cluster name with two worker nodes: ```bash theme={null} curl -fsSL https://tracebloc.io/i.sh | CLUSTER_NAME=my-cluster AGENTS=2 bash ``` ## Cluster Management The installer creates a k3d cluster that runs inside Docker. You can stop it to free resources, start it again later, or delete it entirely. Your data persists in `HOST_DATA_DIR` between stop/start cycles. ```bash theme={null} # Stop — frees CPU/RAM, data persists k3d cluster stop tracebloc # Start — resume where you left off k3d cluster start tracebloc # Delete — removes the cluster entirely k3d cluster delete tracebloc ``` ### View logs The jobs manager is the main tracebloc process. Check its logs when debugging connectivity or job execution issues: ```bash theme={null} kubectl logs -n -l app=manager ``` ### Useful commands Common kubectl commands for inspecting cluster state: ```bash theme={null} kubectl get nodes -o wide # Node status and IPs kubectl get pods -A # All pods across namespaces kubectl get pods -n # Pods in your workspace kubectl get pvc -n # Persistent volume claims kubectl get services -n # Services and endpoints ``` Install logs are saved to `~/.tracebloc/install-*.log`. ## GPU Support GPU is automatic on Linux — the installer detects your hardware and sets up drivers, the container toolkit, and the Kubernetes device plugin. ### NVIDIA (Linux) Fully automatic. The installer: 1. Detects NVIDIA GPUs via `nvidia-smi` or `lspci` 2. Installs drivers if missing (Ubuntu, RHEL/CentOS, Arch) 3. Installs the NVIDIA Container Toolkit and configures Docker 4. Deploys the NVIDIA k8s device plugin into the cluster 5. Passes `--gpus=all` to k3d A reboot may be required after driver installation. Re-run the installer afterward — it picks up where it left off. ### AMD (Linux) Auto-detected. ROCm is installed automatically on Ubuntu and RHEL/CentOS. A logout/login may be needed for full GPU access. ### macOS CPU only, on both Intel and Apple silicon. Training runs inside Linux containers, which on macOS run in a virtual machine with no access to the Apple GPU — so macOS machines train on CPU by design, regardless of device settings. For GPU training, use a machine with an NVIDIA GPU (Linux, or Windows via WSL2), or deploy on [AWS (EKS)](/environment-setup/eks-client-deployment-guide). ### Windows The installer does **not** install GPU drivers on Windows. Pre-install NVIDIA drivers before running the installer. The installer detects them via `nvidia-smi` and configures the cluster to use them. ## Manual Deployment Skip the installer entirely. Use this if you already have a Kubernetes cluster, need custom resource limits, or want full control over the Helm deployment. A single chart — **`tracebloc/client`** — supports AKS, EKS, bare-metal, and OpenShift; choose your platform via values overrides. Reference defaults live at [`client/ci/{aks,eks,bm,oc}-values.yaml`](https://github.com/tracebloc/client/tree/main/client/ci). ### Add the Helm repository ```bash theme={null} helm repo add tracebloc https://tracebloc.github.io/client helm repo update ``` ### Get default values Export the chart's default configuration to customize it: ```bash theme={null} helm show values tracebloc/client > values.yaml ``` ### Configure values.yaml #### Authentication Set your Client ID and password from the [tracebloc client view](https://ai.tracebloc.io/clients): ```yaml theme={null} clientId: "" clientPassword: "" ``` #### Resource Limits for Training Jobs Defaults are sized for typical workloads. Override per job size; for GPU support, requests and limits **must** be equal: ```yaml theme={null} env: RESOURCE_REQUESTS: "cpu=2,memory=8Gi" RESOURCE_LIMITS: "cpu=2,memory=8Gi" GPU_REQUESTS: "" # "nvidia.com/gpu=1" for GPU GPU_LIMITS: "" # "nvidia.com/gpu=1" for GPU RUNTIME_CLASS_NAME: "" # "nvidia" for k3s GPU ``` #### Storage Storage class and PVC sizes: ```yaml theme={null} storageClass: create: true provisioner: "" # set per platform (see ci/*-values.yaml) allowVolumeExpansion: true parameters: {} # Bare-metal only — hostPath-backed PVs at /tracebloc/{data,logs,mysql} hostPath: enabled: false pvc: mysql: 2Gi logs: 10Gi data: 50Gi ``` **The database must stay on local disk.** MySQL/InnoDB is unsafe on NFS/CIFS, so the database and logs always use the local `/tracebloc` tree. To place large **datasets** on a network mount, set the installer's `HOST_DATASET_DIR` — it relocates only the dataset volume (the chart's `hostPath.datasetPath` → `/tracebloc-data`) and runs ingestion as the mount's owner uid, so writes succeed under NFS `root_squash`. Platform snippets (drop into your values file):
AKS ```yaml theme={null} storageClass: create: true provisioner: file.csi.azure.com parameters: skuName: Standard_LRS mountOptions: - dir_mode=0750 - file_mode=0640 - uid=999 - gid=999 - mfsymlinks - cache=strict - actimeo=30 clusterScope: true ```
EKS ```yaml theme={null} storageClass: create: true provisioner: efs.csi.aws.com volumeBindingMode: Immediate reclaimPolicy: Retain mountOptions: [actimeo=30] parameters: directoryPerms: "700" uid: "999" gid: "999" fileSystemId: provisioningMode: efs-ap clusterScope: true ```
Bare-metal / k3s / k3d ```yaml theme={null} hostPath: enabled: true pvcAccessMode: ReadWriteOnce storageClass: create: true provisioner: kubernetes.io/no-provisioner namespace: podSecurity: enforce: "" # hostPath needs the privileged init-mysql-data container enforceVersion: "" clusterScope: true ```
OpenShift ```yaml theme={null} storageClass: create: false name: ocs-storagecluster-cephfs clusterScope: false openshift: scc: enabled: true networkPolicy: training: enabled: true dnsNamespace: openshift-dns dnsSelector: dns.operator.openshift.io/daemonset-dns: default clusterCidrs: - "10.128.0.0/14" - "172.30.0.0/16" ```
#### Docker Registry The chart pulls the client image from a container registry — credentials are required in production. Use a token, not a plaintext password. ```yaml theme={null} dockerRegistry: server: https://index.docker.io/v1/ username: password: email: ``` The chart auto-creates a secret named `{{ .Release.Name }}-regcred`. Omit the `dockerRegistry` block entirely to skip pull-secret creation (e.g. when using a public mirror). #### Proxy (optional) ```yaml theme={null} env: HTTP_PROXY_HOST: "your-proxy.company.com" HTTP_PROXY_PORT: "8080" HTTP_PROXY_USERNAME: "" HTTP_PROXY_PASSWORD: "" ``` #### Auto-upgrade (on by default) Releases of chart `1.3.0+` install a `-auto-upgrade` CronJob that polls `https://tracebloc.github.io/client` daily and runs `helm upgrade --reset-then-reuse-values` whenever a newer chart version is published — so clients auto-update instead of staying pinned to the version they were installed with. ```yaml theme={null} autoUpgrade: enabled: true # set false to opt out schedule: "23 2 * * *" # daily at 02:23 UTC suspend: false # one-shot pause without removing resources repoUrl: "https://tracebloc.github.io/client" repoName: "tracebloc" chartName: "client" timeout: "10m" ``` The CronJob's ServiceAccount is bound to the built-in `cluster-admin` ClusterRole because the chart templates cluster-scoped resources (PriorityClass, StorageClass, ClusterRoleBinding, optionally Namespace). Disable if you need a manual approval gate on upgrades. #### NetworkPolicy hardening for training pods Training pods run untrusted ML code. The chart can apply a NetworkPolicy that denies all ingress and restricts egress — arbitrary pod-to-pod traffic and the Kubernetes API are blocked, while the in-cluster MySQL that serves the training data and the proxy that reports results stay reachable. Direct outbound HTTPS is allowed by default; a stricter lockdown that instead routes it through an in-cluster egress gateway can be enabled per cluster. ```yaml theme={null} networkPolicy: training: enabled: true dnsNamespace: kube-system dnsSelector: {} # empty falls back to {k8s-app: kube-dns} clusterCidrs: - "10.0.0.0/8" - "172.16.0.0/12" - "192.168.0.0/16" ``` Requires a CNI that **enforces** NetworkPolicy: | Platform | Notes | | ---------- | ---------------------------------------------------------------------------------- | | AKS | needs `--network-policy azure` (Azure NPM) or Calico at cluster create | | EKS | needs Calico or Cilium add-on (the default AWS VPC CNI alone does **not** enforce) | | Bare-metal | needs Calico / Cilium / kube-router (Flannel alone does **not** enforce) | | OpenShift | OVN-Kubernetes enforces by default | Leave `enabled: false` on clusters without an enforcing CNI — silently having no protection is worse than explicitly disabling it. The chart's training-pod egress lockdown only blocks traffic if your CNI enforces NetworkPolicy. Verify your CNI before relying on it. #### Resource Monitor and node-agents namespace The `tracebloc-resource-monitor` DaemonSet collects node-level CPU/memory metrics. It mounts `hostPath` volumes (`/proc`, `/sys`) which Pod Security Admission's `restricted` profile bans — so the chart isolates it in a dedicated **privileged** namespace (default `tracebloc-node-agents`). ```yaml theme={null} resourceMonitor: true # set false on clusters where metrics-server cannot be installed nodeAgents: namespace: create: true name: tracebloc-node-agents ``` When `create: false`, create the namespace yourself with the required PSA labels: ```bash theme={null} kubectl create namespace tracebloc-node-agents kubectl label namespace tracebloc-node-agents \ pod-security.kubernetes.io/enforce=privileged \ pod-security.kubernetes.io/warn=privileged \ pod-security.kubernetes.io/audit=privileged ``` The DaemonSet **requires** `metrics-server`. It is bundled on k3d/k3s/AKS, present on OpenShift, and **must be installed manually on EKS** (`kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml`). #### Pod Security Admission labels Training Jobs run untrusted user-supplied ML code. The chart can create the release namespace with Pod Security Admission `warn`/`audit`/`enforce` labels at the `restricted` profile for defense-in-depth: ```yaml theme={null} namespace: create: false # true only on greenfield installs podSecurity: warn: restricted audit: restricted enforce: restricted # set "" for bare-metal hostPath installs ``` When `create: false` (default) and you want PSA labels on an existing namespace: ```bash theme={null} kubectl label namespace \ pod-security.kubernetes.io/warn=restricted \ pod-security.kubernetes.io/audit=restricted \ pod-security.kubernetes.io/enforce=restricted ``` #### Image digest pinning Pin images by content hash for reproducible deploys. When `digest` is set, `tag` is ignored and `imagePullPolicy` drops to `IfNotPresent`. ```yaml theme={null} images: jobsManager: { digest: "sha256:..." } podsMonitor: { digest: "sha256:..." } resourceMonitor: { digest: "sha256:..." } requestsProxy: { digest: "sha256:..." } mysqlClient: { tag: "", digest: "" } busybox: { tag: "1.35", digest: "" } ``` #### PriorityClass and PodDisruptionBudgets The chart pins the MySQL pod with a `tracebloc-data-plane` PriorityClass (value `1000000`) so it survives node-level OOM and scheduling pressure, and applies PDBs to MySQL and the jobs manager. Override only if you run a multi-replica MySQL externally: ```yaml theme={null} priorityClass: create: true name: tracebloc-data-plane value: 1000000 podDisruptionBudget: mysql: { create: true } jobsManager: { create: true } ``` ### Deploy Install the chart into a new namespace: ```bash theme={null} helm upgrade --install tracebloc/client \ --namespace \ --create-namespace \ --values values.yaml ``` ### Upgrade The auto-upgrade CronJob handles routine version bumps. To upgrade manually: ```bash theme={null} helm repo update helm upgrade tracebloc/client \ --namespace \ --reset-then-reuse-values \ --values values.yaml ``` When upgrading **into** chart 1.3.0 from 1.2.x, use `--reset-then-reuse-values` (not plain `--reuse-values`) — the new `autoUpgrade` block did not exist in 1.2.x and a plain reuse fails template rendering. ### Uninstall ```bash theme={null} helm uninstall -n ``` PVCs and the PriorityClass are annotated `helm.sh/resource-policy: keep` so your data and shared cluster resources survive uninstall. To remove them too: ```bash theme={null} kubectl delete pvc --all -n kubectl delete namespace ``` ### Migrating from legacy charts If you installed before chart 1.3.x using `tracebloc/aks`, `tracebloc/eks`, or `tracebloc/bm`, see the [migration guide in the client repo](https://github.com/tracebloc/client/blob/main/client/MIGRATION.md). Key changes: * 4 charts → 1 chart (`tracebloc/client`) with platform values overrides * Auth keys flattened: `jobsManager.env.CLIENT_ID` + `secrets.clientPassword` → top-level `clientId` + `clientPassword` * PVC keys flattened: `clientData` / `clientLogsPvc` / `mysqlPvc` (with `name`, `storage`, `hostPath`) → `pvc.{data,logs,mysql}` (size only) + `hostPath.enabled` for bare-metal * ServiceAccount renamed from `default` to `{{ .Release.Name }}-jobs-manager` * Pull-secret renamed from hard-coded `regcred` to `{{ .Release.Name }}-regcred` * The `namespace` value in the legacy `values.yaml` is gone — use `helm install -n ` instead ## Security Tracebloc is designed so your data never has to leave your network. Here's how: * **Data stays local.** Training data never leaves your infrastructure. Only metadata and metrics are shared with the platform. * **Encrypted.** All communication between client and platform is TLS-encrypted. * **Isolated.** Training runs in containers with restricted system access. Kubernetes namespaces separate workloads from each other. * **Scanned.** Submitted models are analyzed for vulnerabilities before execution on your infrastructure. * **Minimal footprint.** The installer only modifies `~/.tracebloc/` and Docker. No system-wide changes. # Azure AKS Source: https://docs.tracebloc.io/environment-setup/deploy-aks Deploy a tracebloc workspace on Azure Kubernetes Service. **When to pick it** — You're on Azure and want managed Kubernetes with autoscaling and GPU node pools. ## Prerequisites * An AKS cluster, and `kubectl` pointed at it (`az aks get-credentials …`). * **Helm 3.x**. * Your **Client ID** and password from the [clients page](https://ai.tracebloc.io/clients). ## Install ```bash theme={null} helm repo add tracebloc https://tracebloc.github.io/client helm repo update helm show values tracebloc/client > values.yaml # edit per below helm upgrade --install tracebloc tracebloc/client \ -n tracebloc --create-namespace -f values.yaml ``` Set your credentials in `values.yaml` (see [Configuration → Authentication](/environment-setup/configuration#authentication)). ## Verify ```bash theme={null} kubectl get pods -n tracebloc ``` Pods `Running`, your workspace **Online** on the clients page. ## Environment-specific config Use Azure Files for shared storage: ```yaml theme={null} storageClass: create: true provisioner: file.csi.azure.com parameters: skuName: Standard_LRS mountOptions: [dir_mode=0750, file_mode=0640, uid=999, gid=999, mfsymlinks, cache=strict, actimeo=30] clusterScope: true ``` * **NetworkPolicy:** create the AKS cluster with `--network-policy azure` (Azure NPM) or Calico — otherwise the training-pod egress lockdown won't enforce. * `metrics-server` is bundled on AKS. ## Production notes * Use GPU node pools for training workloads; size requests/limits per job. * Day-2 upgrades and rollbacks: see [Operations](/environment-setup/operations). # Bare-metal Source: https://docs.tracebloc.io/environment-setup/deploy-bare-metal Deploy a tracebloc workspace on your own on-prem Kubernetes cluster. **When to pick it** — You already run Kubernetes on-prem (k3s, kubeadm, RKE, …) and want a workspace on it, with full control over scheduling and storage. ## Prerequisites * A running Kubernetes cluster and `kubectl` access. * **Helm 3.x**. * `metrics-server` installed (the resource monitor needs it). * Your **Client ID** and password from the [clients page](https://ai.tracebloc.io/clients). ## Install ```bash theme={null} helm repo add tracebloc https://tracebloc.github.io/client helm repo update helm show values tracebloc/client > values.yaml # edit per below helm upgrade --install tracebloc tracebloc/client \ -n tracebloc --create-namespace -f values.yaml ``` Set your credentials in `values.yaml` (see [Configuration → Authentication](/environment-setup/configuration#authentication)). ## Verify ```bash theme={null} kubectl get pods -n tracebloc ``` Pods `Running`, your workspace **Online** on the clients page. ## Environment-specific config Use hostPath-backed volumes: ```yaml theme={null} hostPath: enabled: true pvcAccessMode: ReadWriteOnce storageClass: create: true provisioner: kubernetes.io/no-provisioner namespace: podSecurity: enforce: "" # hostPath needs the privileged init-mysql-data container clusterScope: true ``` * **NetworkPolicy** (training-pod egress lockdown) only enforces if your CNI supports it — Calico, Cilium, or kube-router. Flannel alone does **not** enforce. ## Production notes * Schedule MySQL and storage on reliable nodes; back up the data PVCs. * Size training compute per job via `RESOURCE_REQUESTS` / `RESOURCE_LIMITS` ([Configuration](/environment-setup/configuration#resource-limits-for-training-jobs)). * Day-2 upgrades and rollbacks: see [Operations](/environment-setup/operations). # Local / k3d Source: https://docs.tracebloc.io/environment-setup/deploy-local Run a tracebloc workspace on a single machine — laptop or on-prem server. Production-capable. **When to pick it** — A single machine you own: a laptop to try things, or an on-prem server you run in production. The installer brings up a self-contained Kubernetes cluster (k3d) inside Docker — you don't need a cluster of your own. ## Prerequisites * A machine: macOS, Linux, or Windows · 2 CPU · 5 GB RAM · 10 GB free disk to run (4 CPU · 16 GB · 50 GB to train on it). * Your **Client ID** and password from the [clients page](https://ai.tracebloc.io/clients). That's it — no Docker or Kubernetes knowledge needed. The installer sets up Docker and the cluster for you. ## Install ```bash theme={null} curl -fsSL https://tracebloc.io/i.sh | bash ``` ```powershell theme={null} irm https://tracebloc.io/i.ps1 | iex ``` See [Quick Start](/environment-setup/quickstart) for the full walkthrough, including the inspect-first option. ## Verify ```bash theme={null} kubectl get pods -A ``` The tracebloc pods should be `Running`, and your workspace should read **Online** on the clients page. ## Environment-specific config Set these as environment variables before the install command (full list in [Configuration](/environment-setup/configuration#installer-options)): ```bash theme={null} curl -fsSL https://tracebloc.io/i.sh | CLUSTER_NAME=my-cluster AGENTS=2 HOST_DATA_DIR=/data/tracebloc bash ``` GPUs are auto-detected on Linux (NVIDIA/AMD) — drivers, container toolkit, and device plugin are installed for you. ## Production notes * **Local is production-capable.** Point it at a server rather than a laptop and it's a real deployment. * Your data persists in `HOST_DATA_DIR` across stop/start cycles (see [Operations](/environment-setup/operations)). * Need more headroom? Re-run the installer on a bigger machine, or add worker nodes with `AGENTS`. * For multi-node high availability, use [bare-metal](/environment-setup/deploy-bare-metal) or a managed cloud instead. # OpenShift Source: https://docs.tracebloc.io/environment-setup/deploy-openshift Deploy a tracebloc workspace on Red Hat OpenShift or OKD. **When to pick it** — You run Red Hat OpenShift (or OKD) and need the workspace to fit its security model (SCCs, OVN networking). ## Prerequisites * An OpenShift cluster, and `oc` / `kubectl` access. * **Helm 3.x**. * Your **Client ID** and password from the [clients page](https://ai.tracebloc.io/clients). ## Install ```bash theme={null} helm repo add tracebloc https://tracebloc.github.io/client helm repo update helm show values tracebloc/client > values.yaml # edit per below helm upgrade --install tracebloc tracebloc/client \ -n tracebloc --create-namespace -f values.yaml ``` Set your credentials in `values.yaml` (see [Configuration → Authentication](/environment-setup/configuration#authentication)). ## Verify ```bash theme={null} oc get pods -n tracebloc ``` Pods `Running`, your workspace **Online** on the clients page. ## Environment-specific config ```yaml theme={null} storageClass: create: false name: ocs-storagecluster-cephfs clusterScope: false openshift: scc: enabled: true # SCC for the privileged resource-monitor networkPolicy: training: enabled: true dnsNamespace: openshift-dns dnsSelector: dns.operator.openshift.io/daemonset-dns: default ``` * OVN-Kubernetes **enforces** NetworkPolicy by default, so the training-pod egress lockdown works out of the box. * `metrics-server` is present on OpenShift. ## Production notes * The bundled SCC grants the resource-monitor the host access it needs — review it against your cluster policy. * Size training compute per job; day-2 management is in [Operations](/environment-setup/operations). # Deployment environments Source: https://docs.tracebloc.io/environment-setup/deployment-environments Run tracebloc anywhere — local, bare-metal, EKS, AKS, or OpenShift. Same chart, same steps, your choice of infrastructure. tracebloc runs the same way everywhere: one chart (`tracebloc/client`), one set of steps, your choice of infrastructure. **Local is a first-class production option** — a workspace on an on-prem server is every bit as real as one on a managed cloud cluster. ## Pick your environment | Environment | Runs on | GPU | Best when | | ------------------------------------------------------------ | --------------------------- | --------------------------------------------- | ------------------------------------------------------- | | [Local / k3d](/environment-setup/deploy-local) | One machine you own | NVIDIA / AMD, auto-detected (macOS: CPU only) | A laptop or a single on-prem server — the fastest start | | [Bare-metal](/environment-setup/deploy-bare-metal) | Your own Kubernetes cluster | Your nodes | You already run on-prem Kubernetes | | [Amazon EKS](/environment-setup/eks-client-deployment-guide) | AWS (managed) | GPU nodegroups | You're on AWS and want managed, autoscaling compute | | [Azure AKS](/environment-setup/deploy-aks) | Azure (managed) | GPU node pools | You're on Azure | | [OpenShift](/environment-setup/deploy-openshift) | OpenShift / OKD | Your nodes | You run Red Hat OpenShift | Just want it running fast on one machine? The [Quick Start](/environment-setup/quickstart) one-liner is the local path with zero configuration. ## Every environment, same shape Each guide follows the same six headings, so you always know where to look: **When to pick it · Prerequisites · Install · Verify · Environment-specific config · Production notes.** Adding a new target later (GKE, on-prem k3s, …) means filling the same template. All environments deploy the same chart — see [Configuration](/environment-setup/configuration) for every value, and [Operations](/environment-setup/operations) for day-2 management. # Amazon EKS Source: https://docs.tracebloc.io/environment-setup/eks-client-deployment-guide Deploy a tracebloc workspace on Amazon EKS using the AWS CLI — networking, GPU support, storage, and security for a production cluster. ## Overview **Use EKS for production** — multi-node, autoscaling, or shared GPU clusters on AWS. For a single machine (a laptop or one server), the [local installer](/environment-setup/setup-guide) is simpler and faster. Running machine learning workloads in the cloud often requires a reliable, secure, and scalable infrastructure—yet setting it up can be complex. This guide walks you through building a complete Amazon EKS (Elastic Kubernetes Service) environment from scratch using the AWS CLI. By following these steps, you'll create a production-ready foundation with networking, GPU-optional compute, storage, and security fully aligned with AWS and Kubernetes best practices. Once the infrastructure is in place, you'll deploy and configure the tracebloc client to securely train and benchmark AI models. This setup ensures that your proprietary data stays within your environment, while still allowing external AI models to be tested and fine-tuned in a controlled, isolated way. The result: a scalable, secure platform for high-performance ML workloads that accelerates collaboration with external experts while maintaining full control over your data and IP. The entire setup takes \~1–2 hours. If the cluster is already up and you are just adding another client to it, skip the cluster-creation steps and go straight to ["Client Configuration"](#5-client-configuration). ## Prerequisites Before proceeding with the EKS infrastructure setup, make sure the following requirements are met: ### AWS Setup #### 1. Create or use an AWS Account * If you don't already have one, [create an AWS account](https://signin.aws.amazon.com/signup?request_type=register). * Your account must have permissions to create and manage EKS resources, VPCs, EC2 instances, and IAM roles. #### 2. Install and configure AWS CLI * [Install the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) on your local machine. * Configure your credentials with: ```bash theme={null} aws configure ``` This prompts you to enter your Access Key ID, Secret Access Key, default region (recommended: `eu-central-1`), and output format. #### 3. Verify your AWS CLI configuration Check if your credentials and region are set correctly: ```bash theme={null} aws configure list ``` If needed, set the region explicitly: ```bash theme={null} aws configure set region eu-central-1 ``` #### Required Permissions Requires permissions for: * Amazon EKS cluster management * VPC and networking resources * EC2 instances and security groups * IAM roles and policies ### Required Tooling & Tracebloc Account * **Helm 3.x**: Install Helm on your local machine. [Installation Guide](https://helm.sh/docs/intro/install/) * **kubectl**: Install kubectl to interact with your EKS cluster. [Installation Guide](https://kubernetes.io/docs/tasks/tools/) * **Tracebloc Account**: You will need your Client ID and Client Password ([from the tracebloc client view](https://ai.tracebloc.io/clients)). * **Docker Registry Credentials**: Docker Hub username, password/token, and email for pulling container images. ### Recommended for Monitoring: Use k9s You can use [k9s](https://k9scli.io/), a terminal-based Kubernetes dashboard, to monitor jobs, pods, and logs in real time. Run `k9s -n ` to get a live view of resources, switch between them instantly, and inspect logs or events with a few keystrokes. Compared to kubectl, it is faster and more convenient. ### Components The EKS infrastructure setup consists of two main parts: Core Infrastructure and Client Deployment. Together, they provide a secure, scalable environment for running ML workloads with the tracebloc client. #### Core Infrastructure **VPC with isolated networking** Creates a dedicated, secure network environment with subnets across multiple Availability Zones for high availability. **EKS Cluster** A managed Kubernetes control plane with auto-scaling nodegroups to run your ML workloads. **IAM Roles and Policies** Granular roles for the cluster and worker nodes following least-privilege principles. **Security Groups** Network-level access controls for pods, nodes, and storage. **EFS Storage System** Shared persistent storage for training datasets and model artifacts, accessible from all nodes. #### Client Deployment **tracebloc Client Application** Deployed into the EKS cluster using Helm, configured with your account credentials and storage. **Monitoring and Verification** Tools for validating that your cluster, workloads, and client are running correctly. By combining these components, you get a production-ready Kubernetes environment tailored for secure, high-performance machine learning workloads. ### Process Flow 1. **Infrastructure Setup** - Create VPC, networking, EKS cluster, and storage 2. **Client Deployment** - Configure and deploy the tracebloc application 3. **Verification** - Validate everything is running correctly ## Security Security is a core consideration when setting up and running ML workloads on EKS. This setup follows AWS and Kubernetes best practices to ensure data protection, secure communication, and controlled access at every layer. ### Data Protection * **Data Locality**: Training data always remains within your infrastructure. Only pre-defined metrics and logs are shared externally. * **Model Encryption**: Model weights are encrypted and never leave your environment. * **Secure Communication**: All platform communication is protected with TLS. ### tracebloc Backend Security * **Code Analysis**: Submitted external models are scanned with the Bandit library to detect vulnerabilities or malicious code. * **Input Validation**: Training scripts and model code undergo strict validation before execution. * **Sandboxed Execution**: Training workloads run in isolated environments with restricted system access. * **Namespace Isolation**: Kubernetes namespaces ensure logical separation from other applications. ### Identity & Access Management **AWS IAM Roles:** * **Cluster Role**: Minimal permissions (`AmazonEKSClusterPolicy`) for cluster management. * **Nodegroup Role**: Least-privilege permissions for worker nodes, networking, container registry, and storage access. **Kubernetes RBAC:** * Cluster roles provide limited permissions for jobs, pods, and deployments. * Service accounts are bound to roles within their namespace, preventing cross-namespace access. ### Network Security * **VPC Isolation**: Dedicated VPC with private subnets and an Internet Gateway for controlled communication. * **Security Groups**: Restrict access to EFS mount targets and cluster traffic. * **Outbound Access**: Limited to required destinations such as `*.amazonaws.com`, `*.docker.io`, and `*.tracebloc.io`. Together, these measures ensure that external models can be deployed safely into your EKS environment without exposing proprietary data or infrastructure. ## Quick Setup Quick Setup runs an automated script that builds the whole cluster in one go. Want step-by-step control (or to customize networking)? Use [Detailed Setup](#detailed-setup) instead. ### Purpose Spin up a production-ready EKS baseline (VPC, subnets, internet gateway, EKS cluster, managed nodegroup, EFS + CSI driver) in one go. Includes basic validation, colored logging, and a cleanup mode. ### What this script does * Creates networking (VPC + 3 public subnets + route to IGW) * Provisions an EKS cluster and a system nodegroup (t3.medium, 2–5 nodes) * Creates EFS and mount targets in all AZs, sets up the EFS CSI driver + storage class * Updates your kubeconfig for kubectl access * Prints a summary and next steps ### Prerequisites * AWS CLI installed and configured (able to run `aws sts get-caller-identity`) * kubectl installed and on PATH * Permissions to create EKS, EC2/VPC, EFS, and IAM resources in the target account * (Recommended) Helm installed for later app deployment ### How to run 1. Save the script below as `setup_eks.sh` 2. Make it executable: `chmod +x setup_eks.sh` 3. (Optional) Edit the configuration variables at the top (REGION, CLUSTER\_NAME, OWNER\_TAG, etc.) 4. Execute: `./setup_eks.sh` 5. When finished, follow the printed "Next steps" to create your Docker registry secret and deploy workloads ### Cleanup (teardown) Run `./setup_eks.sh cleanup` to remove cluster, nodegroup, EFS, subnets, gateway, roles, and VPC (irreversible). ### Tips: * **Costs**: This creates billable resources (EC2, EKS, EFS, data transfer). Remove when not needed. * **Network model**: Subnets are configured to auto-assign public IPs for simplicity. Adjust to private subnets + NAT as needed. * **Kubernetes version**: The script requests `--kubernetes-version 1.32`; update if your region/account supports a different current version. * **Security hardening**: This is a production baseline; harden further for your environment (security groups, private subnets, IRSA, Pod Security/OPA). If you prefer more control over your setup and want to customize the environment to your needs, follow the step-by-step guide below. ## Detailed Setup This section walks through a step-by-step build with AWS CLI and kubectl. It mirrors the Quick Setup but lets you choose your own resource settings (# of CPUs, Memory, VPC CIDRs, instance types, namespace, Helm release name, StorageClass, etc.). Expect about 1–2 hours end-to-end. ### What you'll do (Steps 1–6): 1. **VPC & Network Configuration** — Create an isolated Virtual Private Cloud (VPC) with subnets distributed across three availability zones for high availability, an Internet Gateway for outbound connectivity, and routing tables with proper associations. This provides network isolation and fault tolerance for your cluster infrastructure. 2. **EKS Cluster Setup** — Create the cluster service role and provision the EKS control plane which manages the Kubernetes API server. 3. **EKS Nodegroup Setup** — Create a node service role and provision two managed nodegroups: A system nodegroup for Kubernetes system components and a training nodegroup for ML workloads. Each nodegroup can be customized with different instance types, scaling parameters, and capacity types depending on the work loads and data types. 4. **Storage** — Create an Amazon EFS file system for shared persistent storage, configure a security group that allows NFS traffic from the cluster nodes, and create mount targets in each availability zone. This provides scalable, shared storage for training data as well as weights and logs. 5. **Client Configuration** — Install the Amazon EFS (Elastic File System) CSI driver (Container Storage Interface) in your EKS (Elastic Kubernetes Service) cluster. This driver is what lets Kubernetes automatically create and mount EFS storage volumes. 6. **Client Deployment** — Add the tracebloc Helm repository, configure your deployment values (authentication credentials, registry access, storage settings, resource limits), install the chart into your chosen namespace. Deploy and verify that all pods are running and persistent volume claims are properly bound. **Helm Usage**: Helm is used to install and manage Kubernetes applications. In steps 5 and 6 you will deploy the tracebloc client via the unified `tracebloc/client` chart with EKS-specific values. ## 1. VPC and Network Configuration Your AWS EKS cluster must run in a secure and isolated network with subnets across availability zones, DNS resolution, and internet access. This is provided by an AWS VPC (Virtual Private Cloud), which is a logically isolated section of AWS where you define your own IP address range (CIDR block), subnets, routing, and gateways. This section sets up the foundation. ### VPC Creation VPC provides network isolation, so your workloads are not exposed to the public internet by default. ```bash theme={null} aws ec2 create-vpc \ --cidr-block 10.0.0.0/16 \ --tag-specifications "ResourceType=vpc,Tags=[{Key=owner,Value=}]" ``` Creates an isolated network environment where your EKS cluster runs securely. Uses CIDR (Classless Inter-Domain Routing) block `10.0.0.0/16` to define the IP address range for all resources in the VPC and tags it with the specified owner name. Replace `` with your preferred identifier. Keep the output and the `VPC_ID`for the next steps. ### Enable DNS Hostnames DNS (Domain Name System) support and hostnames let Kubernetes pods and services find each other by name, which is essential for service discovery in Kubernetes, which relies on DNS resolution. ```bash theme={null} aws ec2 modify-vpc-attribute --vpc-id --enable-dns-hostnames ``` Enables DNS resolution so nodes and services can resolve each other by name instead of IP addresses. Find the `VPC_ID`from the previous step or list VPCs using `aws ec2 describe-vpcs`. ### Create Subnets Across Availability Zones Subnets (smaller ranges of IP addresses inside the VPC) are spread across multiple AZs (Availability Zones) to ensure high availability and fault tolerance. EKS requires subnets in at least 2 availability zones for high availability - using 3 zones provides better fault tolerance and load distribution. ```bash theme={null} aws ec2 create-subnet \ --vpc-id \ --cidr-block 10.0.1.0/24 \ --availability-zone eu-central-1a \ --tag-specifications "ResourceType=subnet,Tags=[{Key=owner,Value=}]" aws ec2 create-subnet \ --vpc-id \ --cidr-block 10.0.2.0/24 \ --availability-zone eu-central-1b \ --tag-specifications "ResourceType=subnet,Tags=[{Key=owner,Value=}]" aws ec2 create-subnet \ --vpc-id \ --cidr-block 10.0.3.0/24 \ --availability-zone eu-central-1c \ --tag-specifications "ResourceType=subnet,Tags=[{Key=owner,Value=}]" ``` Creates three subnets with separate CIDR blocks (`10.0.1.0/24`, `10.0.2.0/24`, `10.0.3.0/24`) distributed across different availability zones. Use or create tags if needed. Register the generated `SUBNET_IDs` for the following steps. ### Enable Public IPs on Subnets EKS worker nodes need public IPs to communicate with the EKS control plane, download container images from Dockerhub, and allow external traffic to reach applications. ```bash theme={null} aws ec2 modify-subnet-attribute --subnet-id --map-public-ip-on-launch aws ec2 modify-subnet-attribute --subnet-id --map-public-ip-on-launch aws ec2 modify-subnet-attribute --subnet-id --map-public-ip-on-launch ``` Configures each subnet to automatically assign public IP addresses to new EC2 instances. ### Create and Attach an Internet Gateway An Internet Gateway (IGW) connects your VPC to the internet so nodes can pull container images and reach AWS APIs. ```bash theme={null} aws ec2 create-internet-gateway \ --tag-specifications "ResourceType=internet-gateway,Tags=[{Key=owner,Value=}]" ``` Register the generated INTERNET\_GATEWAY\_ID for the next step: ```bash theme={null} aws ec2 attach-internet-gateway \ --vpc-id \ --internet-gateway-id ``` ### Create Default Route Table to Internet Gateway A route table defines how network traffic is directed within the VPC and out through the IGW. ```bash theme={null} aws ec2 describe-route-tables \ --region eu-central-1 \ --filters Name=vpc-id,Values= \ --query "RouteTables[].RouteTableId" \ --output table ``` This lists the route table IDs linked to your VPC. Pick the main route table ID you want to update, then add a default route: ```bash theme={null} aws ec2 create-route \ --route-table-id \ --destination-cidr-block 0.0.0.0/0 \ --gateway-id ``` This adds a rule that sends all internet-bound traffic (0.0.0.0/0) through the IGW, enabling external connectivity for your nodes. ## 2. EKS Cluster Setup Amazon EKS provides the managed Kubernetes control plane. It needs permissions through AWS IAM (Identity and Access Management) to create and manage resources such as load balancers, security groups, and network interfaces. The cluster itself is the logical container for the API server, linking your VPC networking with the control plane and IAM role. To interact with it you must update your local kubeconfig so kubectl can send commands. Setting this up gives you a working API server that can manage workloads once worker nodes are added in the next step. ### Create EKS Cluster Role EKS needs an IAM role to manage your cluster's control plane and AWS resources: ```bash theme={null} aws iam create-role \ --role-name \ --assume-role-policy-document '{ "Version": "2012-10-17", "Statement": [{ "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": {"Service": "eks.amazonaws.com"} }] }' \ --tags Key=owner,Value= ``` Creates a role with the following parameters: * `--role-name`: Name for your EKS service role * `--assume-role-policy-document`: Trust policy allowing EKS to use this role * `--tags`: Optional resource tags for organization ### Attach EKS Cluster Policy to Role To give the EKS control plane the necessary permissions, you must attach the AmazonEKSClusterPolicy. ```bash theme={null} aws iam attach-role-policy \ --policy-arn arn:aws:iam::aws:policy/AmazonEKSClusterPolicy \ --role-name ``` Adds the AWS-managed EKS cluster policy to the role, giving the control plane its required permissions to manage networking, security groups, or load balancers. ### Create EKS Cluster Create the EKS cluster to provision the managed Kubernetes control plane and connect it to your VPC, subnets, and IAM role. ```bash theme={null} aws eks create-cluster \ --name \ --role-arn arn:aws:iam:::role/ \ --resources-vpc-config subnetIds=,,,endpointPublicAccess=true,publicAccessCidrs=0.0.0.0/0 \ --kubernetes-network-config serviceIpv4Cidr=172.20.0.0/16,ipFamily=ipv4 \ --kubernetes-version 1.32 \ --tags owner= ``` Creates the EKS cluster using the specified role, VPC subnets, and Kubernetes version. Set an appropriate `CLUSTER_NAME`, **expect this to take around 10 minutes**. If you do not have your accound ID ready, run `aws sts get-caller-identity`. ### Configure kubectl Your local kubectl must know the cluster's API endpoint and credentials, otherwise you cannot interact with the cluster you just created: ```bash theme={null} aws eks update-kubeconfig --region eu-central-1 --name ``` Updates your local kubeconfig for kubectl. ### Manage Multiple Clusters (Optional) If you work with several clusters, make sure your context points to the right one. List all contexts: ```bash theme={null} kubectl config get-contexts ``` Find your `CONTEXT_NAME`, then apply it: ```bash theme={null} kubectl config use-context ``` This ensures subsequent kubectl commands apply to the intended cluster. ### Create Application Namespace Namespaces let you isolate your workloads from system components and other applications running in the cluster. Define an appropriate namespace for your setup ```bash theme={null} kubectl create namespace ``` Adds a dedicated namespace for your workloads, keeping them isolated from system components. ## 3. EKS Nodegroup Setup Nodegroups are sets of EC2 instances that act as worker nodes, running your system and training workloads. Each nodegroup needs an IAM role so the nodes can join the cluster and interact with AWS services such as pulling images from registries, attaching EFS storage, and sending logs. It is best practice to create at least two groups: a small system nodegroup to host cluster services and a training nodegroup sized for your ML workloads. The training nodegroup can be CPU-based for general jobs or GPU-based for deep learning, ensuring that heavy jobs do not interfere with core Kubernetes functions. ### Create Nodegroup Role Worker nodes need an IAM role to join the cluster and access AWS services. ```bash theme={null} aws iam create-role \ --assume-role-policy-document '{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Action": "sts:AssumeRole", "Principal": { "Service": ["ec2.amazonaws.com"] } }] }' \ --role-name \ --tags Key=owner,Value= ``` Creates an IAM role that nodes can assume, allowing them to join the cluster and interact with AWS services. Create an appropriate `NODEGROUP_ROLE_NAME`. ### Attach Required Policies Attach minimum required AWS-managed policies so the nodes have permissions: ```bash theme={null} aws iam attach-role-policy \ --policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy \ --role-name aws iam attach-role-policy \ --policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly \ --role-name aws iam attach-role-policy \ --policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy \ --role-name ``` * **AmazonEKSWorkerNodePolicy:** lets nodes communicate with the cluster control plane * **AmazonEC2ContainerRegistryReadOnly:** allows pulling images from ECR * **AmazonEKS\_CNI\_Policy:** required for pod networking via the Container Network Interface (CNI) plugin ### Create Managed Nodegroups Now let\`s create two nodegroups: A system nodegroup that runs critical Kubernetes components (CoreDNS, kube-proxy, Container Network Interface (CNI), Storage Interface drivers (CSI), metrics-server, etc.) and a training nodegroup that runs your machine learning workloads. This separation ensures cluster stability even under heavy training load. #### System Nodegroup It is recommended to use [AWS EC2 instance type t3.medium](https://aws.amazon.com/ec2/instance-types/t3/) for system pods as they are relatively cheap and sufficient. Spread nodes across three Availability Zones for resilience, set ON\_DEMAND for reliability and label as "system": ```bash theme={null} aws eks create-nodegroup \ --cluster-name \ --nodegroup-name \ --scaling-config minSize=2,maxSize=5,desiredSize=2 \ --subnets \ --node-role arn:aws:iam:::role/ \ --instance-types t3.medium \ --ami-type AL2_x86_64 \ --capacity-type ON_DEMAND \ --update-config maxUnavailable=1 \ --labels type=system \ --tags owner= ``` Creates a nodegroup with `t3.medium` instances (2 vCPUs, 4 GiB memory) spread across three AZs. The group scales between 2 and 5 nodes (EC2s), each node is labeled for system workloads. Set an appropriate `SYSTEM_NODEGROUP_NAME`. Always make sure to use `AL2_x86_64` for system nodes so that the data ingestor runs on this node, too. #### Training Nodegroup This group runs your ML training workloads — size it for your dataset, model type, number of parallel workloads, and whether you need GPUs. Refer to the [EC2 instance types list](https://aws.amazon.com/ec2/instance-types) and [EKS managed nodegroups docs](https://docs.aws.amazon.com/eks/latest/userguide/create-managed-node-group.html) for guidance. ```bash theme={null} aws eks create-nodegroup \ --cluster-name \ --nodegroup-name \ --scaling-config minSize=0,maxSize=5,desiredSize=2 \ --subnets \ --node-role arn:aws:iam:::role/ \ --instance-types \ --ami-type \ --capacity-type ON_DEMAND \ --update-config maxUnavailable=1 \ --labels trainingset=