Training Jobs: Built-in Algorithms vs Custom Containers
Every SageMaker training job runs a Docker container. The only question is who wrote it: AWS, you plus a framework, or entirely you.
Busque em todas as páginas da documentação
Every SageMaker training job runs a Docker container. The only question is who wrote it: AWS, you plus a framework, or entirely you.
CreateTrainingJob looks almost identical either way - the difference lives in one field, AlgorithmSpecification.TrainingImage, and in what you put in HyperParameters. This page compares the two ends of that spectrum so you can pick the cheapest path for the problem in front of you.
Quick-reference recipe card - copy-paste ready.
# --- Python (boto3) ---
import boto3
sm = boto3.client("sagemaker", region_name="us-east-1")
common = dict(
RoleArn="arn:aws:iam::111122223333:role/SageMakerExecutionRole",
InputDataConfig=[{
"ChannelName": "train",
"DataSource": {"S3DataSource": {"S3DataType": "S3Prefix",
"S3Uri": "s3://my-ml-bucket/train/",
"S3DataDistributionType": "FullyReplicated"}},
}],
OutputDataConfig={"S3OutputPath": "s3://my-ml-bucket/output/"},
ResourceConfig={"InstanceType": "ml.m5.xlarge", "InstanceCount": 1, "VolumeSizeInGB": 30},
StoppingCondition={"MaxRuntimeInSeconds": 3600},
)
# Built-in algorithm: AWS's image, algorithm-defined hyperparameters, no training code.
sm.create_training_job(
TrainingJobName="builtin-xgb-001",
AlgorithmSpecification={"TrainingImage": "683313688378.dkr.ecr.us-east-1.amazonaws.com/xgboost:1.7-1",
"TrainingInputMode": "File"},
HyperParameters={"num_round": "100", "objective": "binary:logistic"},
**common,
)
# Custom container: your image, your own hyperparameters, your own training script inside.
sm.create_training_job(
TrainingJobName="custom-001",
AlgorithmSpecification={"TrainingImage": "111122223333.dkr.ecr.us-east-1.amazonaws.com/my-trainer:1.0",
"TrainingInputMode": "File"},
HyperParameters={"epochs": "10", "learning_rate": "0.001"},
**common,
)// --- TypeScript (AWS SDK v3) ---
import { SageMakerClient, CreateTrainingJobCommand } from "@aws-sdk/client-sagemaker";
const sm = new SageMakerClient({ region: "us-east-1" });
const common = {
RoleArn: "arn:aws:iam::111122223333:role/SageMakerExecutionRole",
InputDataConfig: [{
ChannelName: "train",
DataSource: { S3DataSource: { S3DataType: "S3Prefix",
S3Uri: "s3://my-ml-bucket/train/",
S3DataDistributionType: "FullyReplicated" } },
}],
OutputDataConfig: { S3OutputPath: "s3://my-ml-bucket/output/" },
ResourceConfig: { InstanceType: "ml.m5.xlarge", InstanceCount: 1, VolumeSizeInGB: 30 },
StoppingCondition: { MaxRuntimeInSeconds: 3600 },
};
// Built-in algorithm: AWS's image, algorithm-defined hyperparameters, no training code.
await sm.send(new CreateTrainingJobCommand({
TrainingJobName: "builtin-xgb-001",
AlgorithmSpecification: { TrainingImage: "683313688378.dkr.ecr.us-east-1.amazonaws.com/xgboost:1.7-1",
TrainingInputMode: "File" },
HyperParameters: { num_round: "100", objective: "binary:logistic" },
...common,
}));
// Custom container: your image, your own hyperparameters, your own training script inside.
await sm.send(new CreateTrainingJobCommand({
TrainingJobName: "custom-001",
AlgorithmSpecification: { TrainingImage: "111122223333.dkr.ecr.us-east-1.amazonaws.com/my-trainer:1.0",
TrainingInputMode: "File" },
HyperParameters: { epochs: "10", learning_rate: "0.001" },
...common,
}));When to reach for this:
Describe both jobs after they finish and compare what each one required to get there.
# --- Python (boto3) ---
for name in ["builtin-xgb-001", "custom-001"]:
sm.get_waiter("training_job_completed_or_stopped").wait(
TrainingJobName=name, WaiterConfig={"Delay": 30, "MaxAttempts": 120},
)
desc = sm.describe_training_job(TrainingJobName=name)
print(name, "->", desc["TrainingJobStatus"], desc.get("AlgorithmSpecification", {}).get("TrainingImage"))// --- TypeScript (AWS SDK v3) ---
import { DescribeTrainingJobCommand, waitUntilTrainingJobCompletedOrStopped } from "@aws-sdk/client-sagemaker";
for (const name of ["builtin-xgb-001", "custom-001"]) {
await waitUntilTrainingJobCompletedOrStopped({ client: sm, maxWaitTime: 3600 }, { TrainingJobName: name });
const desc = await sm.send(new DescribeTrainingJobCommand({ TrainingJobName: name }));
console.log(name, "->", desc.TrainingJobStatus, desc.AlgorithmSpecification?.TrainingImage);
}What this demonstrates:
TrainingImage ran - AWS's or yours.DescribeTrainingJob tells you which path was "correct" - both produce a model.tar.gz if they succeed.A built-in algorithm is an AWS-published, AWS-maintained container image referenced directly in TrainingImage. You supply data in the format it expects and hyperparameters from its documented list (like XGBoost's num_round and objective). You write zero training code. AWS handles the model logic, framework version, and container internals.
The trade-off is fit: built-in algorithms cover common, well-understood problem shapes (gradient-boosted trees, linear models, common vision and text architectures). If your modeling approach does not match one, there is no partial credit - you move to a container you control.
Between the two extremes, AWS also publishes framework-specific training images (for popular deep learning and ML frameworks) designed to run a script you provide rather than a fixed algorithm. Conceptually, you still point TrainingImage at an AWS-maintained image, but the container's entrypoint expects to find and execute your training script, which SageMaker fetches from S3 or bundles in at build time depending on the workflow.
This middle path avoids writing a Dockerfile while giving you full control over model code - hedge on the exact packaging convention for a given framework version, since it varies and evolves; check that framework's current SageMaker documentation before relying on specifics.
At the far end, TrainingImage points at an image in your own ECR repository. You write the Dockerfile, install every dependency, and implement the SageMaker training contract yourself (fixed script location, SM_* environment variables, reading channels from /opt/ml/input/data/<channel>). This is covered in depth on the bring-your-own-container page. It costs the most setup but has no ceiling on what the training logic can do.
In practice, the decision comes down to three questions in order: does a built-in algorithm's documented parameter set describe your problem; if not, does a framework container let you keep your model code without owning a Dockerfile; and only if neither fits, do you own the full container. Each step down costs more setup time and more operational surface (your own image to patch and rebuild) in exchange for more control.
HyperParameters.TrainingImage URI from another region. Built-in algorithm images are published per-region. Fix: look up the URI for your training job's region rather than reusing one from documentation examples.TrainingInputMode behaves the same everywhere. File downloads data before training starts; some workflows expect streaming instead. Fix: confirm the image's expected input mode before assuming File is correct for large datasets.SM_CHANNEL_*/write to SM_MODEL_DIR will fail or silently produce no artifact. Fix: implement the contract described on the bring-your-own-container page before troubleshooting elsewhere.| Alternative | Use When | Don't Use When |
|---|---|---|
| Built-in algorithm | Problem matches a documented algorithm (tabular, common CV/NLP tasks) | Your modeling approach isn't one AWS publishes |
| Framework container + your script | You want a specific framework but not a Dockerfile | You need dependencies the framework image doesn't include |
| Fully custom container | You need full control over dependencies, runtime, or training logic | A built-in or framework option already fits - it costs more to maintain |
| Local/notebook training, then import a model | Small, exploratory work with no need for managed infrastructure | You need reproducible, scalable, or distributed training runs |
Mainly one field: AlgorithmSpecification.TrainingImage, plus which HyperParameters are meaningful. The rest of CreateTrainingJob - data channels, resources, stopping condition - stays the same shape either way.
No. Built-in algorithms are AWS-maintained images; you supply only data and hyperparameters, never a container or training script.
An AWS-published image for a specific ML framework that expects to run a training script you provide, rather than a fixed algorithm. It saves you from writing a Dockerfile while keeping your model code under your control. Confirm current packaging conventions in that framework's SageMaker documentation, since they can vary by version.
Yes - InputDataConfig and S3 data have no dependency on which image reads them. Your custom container just needs to parse whatever format you put in S3 and expose it correctly to the training script.
Check the current SageMaker built-in algorithms documentation for the per-region ECR URI table for the algorithm and version you want. These URIs differ by region and are updated as AWS ships new algorithm versions.
Not inherently - a well-written custom container can perform identically to a built-in one. The cost is operational: you own building, testing, and patching the image over time, which a built-in algorithm image never requires.
Stack versions: This page was written for boto3 1.43.x (Python 3.10+) and the AWS SDK for JavaScript v3 (Node.js 18+).
Revisado por Chris St. John·Última atualização: 24 de jul. de 2026