@aws/ml-container-creator 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/LICENSE-THIRD-PARTY +68620 -0
- package/NOTICE +2 -0
- package/README.md +106 -0
- package/bin/cli.js +365 -0
- package/config/defaults.json +32 -0
- package/config/presets/transformers-djl.json +26 -0
- package/config/presets/transformers-gpu.json +24 -0
- package/config/presets/transformers-lmi.json +27 -0
- package/package.json +129 -0
- package/servers/README.md +419 -0
- package/servers/base-image-picker/catalogs/model-servers.json +1191 -0
- package/servers/base-image-picker/catalogs/python-slim.json +38 -0
- package/servers/base-image-picker/catalogs/triton-backends.json +51 -0
- package/servers/base-image-picker/catalogs/triton.json +38 -0
- package/servers/base-image-picker/index.js +495 -0
- package/servers/base-image-picker/manifest.json +17 -0
- package/servers/base-image-picker/package.json +15 -0
- package/servers/hyperpod-cluster-picker/LICENSE +202 -0
- package/servers/hyperpod-cluster-picker/index.js +424 -0
- package/servers/hyperpod-cluster-picker/manifest.json +14 -0
- package/servers/hyperpod-cluster-picker/package.json +17 -0
- package/servers/instance-recommender/LICENSE +202 -0
- package/servers/instance-recommender/catalogs/instances.json +852 -0
- package/servers/instance-recommender/index.js +284 -0
- package/servers/instance-recommender/manifest.json +16 -0
- package/servers/instance-recommender/package.json +15 -0
- package/servers/lib/LICENSE +202 -0
- package/servers/lib/bedrock-client.js +160 -0
- package/servers/lib/custom-validators.js +46 -0
- package/servers/lib/dynamic-resolver.js +36 -0
- package/servers/lib/package.json +11 -0
- package/servers/lib/schemas/image-catalog.schema.json +185 -0
- package/servers/lib/schemas/instances.schema.json +124 -0
- package/servers/lib/schemas/manifest.schema.json +64 -0
- package/servers/lib/schemas/model-catalog.schema.json +91 -0
- package/servers/lib/schemas/regions.schema.json +26 -0
- package/servers/lib/schemas/triton-backends.schema.json +51 -0
- package/servers/model-picker/catalogs/jumpstart-public.json +66 -0
- package/servers/model-picker/catalogs/popular-diffusors.json +88 -0
- package/servers/model-picker/catalogs/popular-transformers.json +226 -0
- package/servers/model-picker/index.js +1693 -0
- package/servers/model-picker/manifest.json +18 -0
- package/servers/model-picker/package.json +20 -0
- package/servers/region-picker/LICENSE +202 -0
- package/servers/region-picker/catalogs/regions.json +263 -0
- package/servers/region-picker/index.js +230 -0
- package/servers/region-picker/manifest.json +16 -0
- package/servers/region-picker/package.json +15 -0
- package/src/app.js +1007 -0
- package/src/copy-tpl.js +77 -0
- package/src/lib/accelerator-validator.js +39 -0
- package/src/lib/asset-manager.js +385 -0
- package/src/lib/aws-profile-parser.js +181 -0
- package/src/lib/bootstrap-command-handler.js +1647 -0
- package/src/lib/bootstrap-config.js +238 -0
- package/src/lib/ci-register-helpers.js +124 -0
- package/src/lib/ci-report-helpers.js +158 -0
- package/src/lib/ci-stage-helpers.js +268 -0
- package/src/lib/cli-handler.js +529 -0
- package/src/lib/comment-generator.js +544 -0
- package/src/lib/community-reports-validator.js +91 -0
- package/src/lib/config-manager.js +2106 -0
- package/src/lib/configuration-exporter.js +204 -0
- package/src/lib/configuration-manager.js +695 -0
- package/src/lib/configuration-matcher.js +221 -0
- package/src/lib/cpu-validator.js +36 -0
- package/src/lib/cuda-validator.js +57 -0
- package/src/lib/deployment-config-resolver.js +103 -0
- package/src/lib/deployment-entry-schema.js +125 -0
- package/src/lib/deployment-registry.js +598 -0
- package/src/lib/docker-introspection-validator.js +51 -0
- package/src/lib/engine-prefix-resolver.js +60 -0
- package/src/lib/huggingface-client.js +172 -0
- package/src/lib/key-value-parser.js +37 -0
- package/src/lib/known-flags-validator.js +200 -0
- package/src/lib/manifest-cli.js +280 -0
- package/src/lib/mcp-client.js +303 -0
- package/src/lib/mcp-command-handler.js +532 -0
- package/src/lib/neuron-validator.js +80 -0
- package/src/lib/parameter-schema-validator.js +284 -0
- package/src/lib/prompt-runner.js +1349 -0
- package/src/lib/prompts.js +1138 -0
- package/src/lib/registry-command-handler.js +519 -0
- package/src/lib/registry-loader.js +198 -0
- package/src/lib/rocm-validator.js +80 -0
- package/src/lib/schema-validator.js +157 -0
- package/src/lib/sensitive-redactor.js +59 -0
- package/src/lib/template-engine.js +156 -0
- package/src/lib/template-manager.js +341 -0
- package/src/lib/validation-engine.js +314 -0
- package/src/prompt-adapter.js +63 -0
- package/templates/Dockerfile +300 -0
- package/templates/IAM_PERMISSIONS.md +84 -0
- package/templates/MIGRATION.md +488 -0
- package/templates/PROJECT_README.md +439 -0
- package/templates/TEMPLATE_SYSTEM.md +243 -0
- package/templates/buildspec.yml +64 -0
- package/templates/code/chat_template.jinja +1 -0
- package/templates/code/flask/gunicorn_config.py +35 -0
- package/templates/code/flask/wsgi.py +10 -0
- package/templates/code/model_handler.py +387 -0
- package/templates/code/serve +300 -0
- package/templates/code/serve.py +175 -0
- package/templates/code/serving.properties +105 -0
- package/templates/code/start_server.py +39 -0
- package/templates/code/start_server.sh +39 -0
- package/templates/diffusors/Dockerfile +72 -0
- package/templates/diffusors/patch_image_api.py +35 -0
- package/templates/diffusors/serve +115 -0
- package/templates/diffusors/start_server.sh +114 -0
- package/templates/do/.gitkeep +1 -0
- package/templates/do/README.md +541 -0
- package/templates/do/build +83 -0
- package/templates/do/ci +681 -0
- package/templates/do/clean +811 -0
- package/templates/do/config +260 -0
- package/templates/do/deploy +1560 -0
- package/templates/do/export +306 -0
- package/templates/do/logs +319 -0
- package/templates/do/manifest +12 -0
- package/templates/do/push +119 -0
- package/templates/do/register +580 -0
- package/templates/do/run +113 -0
- package/templates/do/submit +417 -0
- package/templates/do/test +1147 -0
- package/templates/hyperpod/configmap.yaml +24 -0
- package/templates/hyperpod/deployment.yaml +71 -0
- package/templates/hyperpod/pvc.yaml +42 -0
- package/templates/hyperpod/service.yaml +17 -0
- package/templates/nginx-diffusors.conf +74 -0
- package/templates/nginx-predictors.conf +47 -0
- package/templates/nginx-tensorrt.conf +74 -0
- package/templates/requirements.txt +61 -0
- package/templates/sample_model/test_inference.py +123 -0
- package/templates/sample_model/train_abalone.py +252 -0
- package/templates/test/test_endpoint.sh +79 -0
- package/templates/test/test_local_image.sh +80 -0
- package/templates/test/test_model_handler.py +180 -0
- package/templates/triton/Dockerfile +128 -0
- package/templates/triton/config.pbtxt +163 -0
- package/templates/triton/model.py +130 -0
- package/templates/triton/requirements.txt +11 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration Matcher
|
|
3
|
+
*
|
|
4
|
+
* Finds best matching configurations for user selections.
|
|
5
|
+
* Supports exact matching, fuzzy version matching, and pattern matching.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
class ConfigurationMatcher {
|
|
9
|
+
constructor(frameworkRegistry = {}, modelRegistry = {}) {
|
|
10
|
+
this.frameworkRegistry = frameworkRegistry;
|
|
11
|
+
this.modelRegistry = modelRegistry;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Match framework configuration
|
|
16
|
+
* Tries exact match first, then finds closest compatible version
|
|
17
|
+
* @param {string} framework - Framework name
|
|
18
|
+
* @param {string} version - Framework version
|
|
19
|
+
* @returns {Object|null} Framework configuration or null if not found
|
|
20
|
+
*/
|
|
21
|
+
matchFramework(framework, version) {
|
|
22
|
+
if (!Object.hasOwn(this.frameworkRegistry, framework)) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
const frameworkVersions = this.frameworkRegistry[framework];
|
|
26
|
+
|
|
27
|
+
// Exact match first
|
|
28
|
+
if (Object.hasOwn(frameworkVersions, version)) {
|
|
29
|
+
return {
|
|
30
|
+
...frameworkVersions[version],
|
|
31
|
+
matchType: 'exact',
|
|
32
|
+
matchedVersion: version
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Find closest compatible version
|
|
37
|
+
const closestMatch = this.findClosestVersion(frameworkVersions, version);
|
|
38
|
+
if (closestMatch) {
|
|
39
|
+
return {
|
|
40
|
+
...closestMatch.config,
|
|
41
|
+
matchType: 'fuzzy',
|
|
42
|
+
matchedVersion: closestMatch.version,
|
|
43
|
+
requestedVersion: version
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Find closest compatible version using semantic versioning
|
|
52
|
+
* @param {Object} versions - Available versions object
|
|
53
|
+
* @param {string} targetVersion - Target version to match
|
|
54
|
+
* @returns {Object|null} Object with {version, config} or null
|
|
55
|
+
*/
|
|
56
|
+
findClosestVersion(versions, targetVersion) {
|
|
57
|
+
const availableVersions = Object.keys(versions);
|
|
58
|
+
if (availableVersions.length === 0) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const target = this.parseVersion(targetVersion);
|
|
63
|
+
if (!target) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
let bestMatch = null;
|
|
68
|
+
let smallestDiff = Infinity;
|
|
69
|
+
|
|
70
|
+
for (const version of availableVersions) {
|
|
71
|
+
const current = this.parseVersion(version);
|
|
72
|
+
if (!current) continue;
|
|
73
|
+
|
|
74
|
+
// Calculate version distance
|
|
75
|
+
const diff = this.calculateVersionDistance(target, current);
|
|
76
|
+
|
|
77
|
+
// Prefer versions that are >= target (forward compatible)
|
|
78
|
+
// But also consider older versions if no newer ones exist
|
|
79
|
+
if (diff < smallestDiff) {
|
|
80
|
+
smallestDiff = diff;
|
|
81
|
+
bestMatch = { version, config: versions[version] };
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return bestMatch;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Parse semantic version string into components
|
|
90
|
+
* @param {string} versionString - Version string (e.g., "1.2.3")
|
|
91
|
+
* @returns {Object|null} Object with {major, minor, patch} or null
|
|
92
|
+
*/
|
|
93
|
+
parseVersion(versionString) {
|
|
94
|
+
if (!versionString || typeof versionString !== 'string') {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Remove 'v' prefix if present
|
|
99
|
+
const cleaned = versionString.replace(/^v/, '');
|
|
100
|
+
|
|
101
|
+
// Match semantic version pattern
|
|
102
|
+
const match = cleaned.match(/^(\d+)(?:\.(\d+))?(?:\.(\d+))?/);
|
|
103
|
+
if (!match) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
major: parseInt(match[1], 10),
|
|
109
|
+
minor: parseInt(match[2] || '0', 10),
|
|
110
|
+
patch: parseInt(match[3] || '0', 10)
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Calculate distance between two versions
|
|
116
|
+
* Lower distance means closer match
|
|
117
|
+
* @param {Object} target - Target version {major, minor, patch}
|
|
118
|
+
* @param {Object} current - Current version {major, minor, patch}
|
|
119
|
+
* @returns {number} Distance value
|
|
120
|
+
*/
|
|
121
|
+
calculateVersionDistance(target, current) {
|
|
122
|
+
// Major version difference is most significant
|
|
123
|
+
const majorDiff = Math.abs(current.major - target.major) * 10000;
|
|
124
|
+
|
|
125
|
+
// Minor version difference
|
|
126
|
+
const minorDiff = Math.abs(current.minor - target.minor) * 100;
|
|
127
|
+
|
|
128
|
+
// Patch version difference
|
|
129
|
+
const patchDiff = Math.abs(current.patch - target.patch);
|
|
130
|
+
|
|
131
|
+
// Prefer newer versions slightly (small penalty for older versions)
|
|
132
|
+
const directionPenalty = current.major < target.major ? 1 :
|
|
133
|
+
current.major === target.major && current.minor < target.minor ? 0.5 :
|
|
134
|
+
current.major === target.major && current.minor === target.minor && current.patch < target.patch ? 0.1 :
|
|
135
|
+
0;
|
|
136
|
+
|
|
137
|
+
return majorDiff + minorDiff + patchDiff + directionPenalty;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Match model configuration
|
|
142
|
+
* Checks exact match first, then pattern matching
|
|
143
|
+
* @param {string} modelId - Model ID (e.g., "meta-llama/Llama-2-7b-chat-hf")
|
|
144
|
+
* @returns {Object|null} Model configuration or null if not found
|
|
145
|
+
*/
|
|
146
|
+
matchModel(modelId) {
|
|
147
|
+
if (!modelId) {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Check exact match first
|
|
152
|
+
if (Object.hasOwn(this.modelRegistry, modelId)) {
|
|
153
|
+
return {
|
|
154
|
+
...this.modelRegistry[modelId],
|
|
155
|
+
matchType: 'exact',
|
|
156
|
+
matchedPattern: modelId
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Try pattern matching
|
|
161
|
+
const patternMatch = this.matchModelPattern(modelId);
|
|
162
|
+
if (patternMatch) {
|
|
163
|
+
return {
|
|
164
|
+
...patternMatch.config,
|
|
165
|
+
matchType: 'pattern',
|
|
166
|
+
matchedPattern: patternMatch.pattern,
|
|
167
|
+
modelId
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Match model by pattern (e.g., "mistral*" matches "mistralai/Mistral-7B-v0.1")
|
|
176
|
+
* @param {string} modelId - Model ID to match
|
|
177
|
+
* @returns {Object|null} Object with {pattern, config} or null
|
|
178
|
+
*/
|
|
179
|
+
matchModelPattern(modelId) {
|
|
180
|
+
if (!modelId) {
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
for (const [pattern, config] of Object.entries(this.modelRegistry)) {
|
|
185
|
+
if (this.matchesPattern(modelId, pattern)) {
|
|
186
|
+
return { pattern, config };
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Check if a model ID matches a pattern
|
|
195
|
+
* Supports wildcards (*) and case-insensitive matching
|
|
196
|
+
* @param {string} modelId - Model ID to test
|
|
197
|
+
* @param {string} pattern - Pattern to match against
|
|
198
|
+
* @returns {boolean} True if matches
|
|
199
|
+
*/
|
|
200
|
+
matchesPattern(modelId, pattern) {
|
|
201
|
+
if (!modelId || !pattern) {
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Exact match (no wildcards)
|
|
206
|
+
if (!pattern.includes('*')) {
|
|
207
|
+
return modelId.toLowerCase() === pattern.toLowerCase();
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Convert pattern to regex
|
|
211
|
+
// Escape special regex characters except *
|
|
212
|
+
const regexPattern = pattern
|
|
213
|
+
.replace(/[.+?^${}()|[\]\\]/g, '\\$&') // Escape special chars
|
|
214
|
+
.replace(/\*/g, '.*'); // Convert * to .*
|
|
215
|
+
|
|
216
|
+
const regex = new RegExp(`^${regexPattern}$`, 'i'); // Case-insensitive
|
|
217
|
+
return regex.test(modelId);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export default ConfigurationMatcher;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import AcceleratorValidator from './accelerator-validator.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CPU accelerator validator.
|
|
5
|
+
* CPU-based inference is always compatible (no version requirements).
|
|
6
|
+
*
|
|
7
|
+
* Requirements: 4.9
|
|
8
|
+
*/
|
|
9
|
+
export default class CpuValidator extends AcceleratorValidator {
|
|
10
|
+
/**
|
|
11
|
+
* Validate CPU compatibility.
|
|
12
|
+
* CPU is always compatible - no version checking needed.
|
|
13
|
+
*
|
|
14
|
+
* @param {Object} frameworkConfig - Framework accelerator requirements
|
|
15
|
+
* @param {Object} instanceConfig - Instance accelerator capabilities
|
|
16
|
+
* @returns {Object} ValidationResult
|
|
17
|
+
*/
|
|
18
|
+
validate(_frameworkConfig, _instanceConfig) {
|
|
19
|
+
return {
|
|
20
|
+
compatible: true,
|
|
21
|
+
info: 'CPU-based inference (no accelerator version requirements)'
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Get version mismatch message.
|
|
27
|
+
* Not used for CPU since it's always compatible.
|
|
28
|
+
*
|
|
29
|
+
* @param {string} required - Required version
|
|
30
|
+
* @param {Array<string>|string} provided - Provided version(s)
|
|
31
|
+
* @returns {string} Empty string (not used for CPU)
|
|
32
|
+
*/
|
|
33
|
+
getVersionMismatchMessage(_required, _provided) {
|
|
34
|
+
return ''; // Not used for CPU
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import AcceleratorValidator from './accelerator-validator.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CUDA-specific accelerator validator.
|
|
5
|
+
* Implements CUDA major.minor version comparison.
|
|
6
|
+
*
|
|
7
|
+
* Requirements: 4.11, 4.12, 4.13, 4.14, 4.22
|
|
8
|
+
*/
|
|
9
|
+
export default class CudaValidator extends AcceleratorValidator {
|
|
10
|
+
/**
|
|
11
|
+
* Validate CUDA version compatibility.
|
|
12
|
+
* CUDA uses major.minor versioning (e.g., 12.1, 11.8).
|
|
13
|
+
*
|
|
14
|
+
* @param {Object} frameworkConfig - Framework accelerator requirements
|
|
15
|
+
* @param {Object} instanceConfig - Instance accelerator capabilities
|
|
16
|
+
* @returns {Object} ValidationResult
|
|
17
|
+
*/
|
|
18
|
+
validate(frameworkConfig, instanceConfig) {
|
|
19
|
+
const required = frameworkConfig.accelerator;
|
|
20
|
+
const provided = instanceConfig.accelerator;
|
|
21
|
+
|
|
22
|
+
// Parse required CUDA version (major.minor)
|
|
23
|
+
const requiredMajor = parseInt(required.version.split('.')[0]);
|
|
24
|
+
const requiredMinor = parseInt(required.version.split('.')[1]);
|
|
25
|
+
|
|
26
|
+
// Check if instance supports required CUDA version
|
|
27
|
+
// Instance must have same major version and >= minor version
|
|
28
|
+
const compatibleVersions = provided.versions.filter(v => {
|
|
29
|
+
const [major, minor] = v.split('.').map(Number);
|
|
30
|
+
return major === requiredMajor && minor >= requiredMinor;
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
if (compatibleVersions.length === 0) {
|
|
34
|
+
return {
|
|
35
|
+
compatible: false,
|
|
36
|
+
error: this.getVersionMismatchMessage(required.version, provided.versions)
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return {
|
|
41
|
+
compatible: true,
|
|
42
|
+
info: `Using CUDA ${compatibleVersions[0]} (compatible with required ${required.version})`
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Get user-friendly error message for CUDA version mismatch.
|
|
48
|
+
*
|
|
49
|
+
* @param {string} required - Required CUDA version
|
|
50
|
+
* @param {Array<string>} provided - Provided CUDA versions
|
|
51
|
+
* @returns {string} User-friendly error message
|
|
52
|
+
*/
|
|
53
|
+
getVersionMismatchMessage(required, provided) {
|
|
54
|
+
return `Framework requires CUDA ${required}, but instance only supports ${provided.join(', ')}. ` +
|
|
55
|
+
'Consider using ml.g5 or ml.g6 instances for CUDA 12.x support.';
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DeploymentConfigResolver
|
|
3
|
+
*
|
|
4
|
+
* Decomposes a flat deployment-config string into a structured
|
|
5
|
+
* { architecture, backend, engine } triple. This is the single source
|
|
6
|
+
* of truth for all valid deployment-config values, replacing the
|
|
7
|
+
* scattered split('-') logic that was previously in ConfigManager,
|
|
8
|
+
* PromptRunner, and index.js.
|
|
9
|
+
*
|
|
10
|
+
* Requirements: 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Canonical mapping from deployment-config strings to structured parts.
|
|
15
|
+
* 2 http + 5 transformers + 7 triton + 1 diffusors = 15 total configs.
|
|
16
|
+
*/
|
|
17
|
+
const CANONICAL_CONFIGS = new Map([
|
|
18
|
+
// HTTP architecture (2)
|
|
19
|
+
['http-flask', { architecture: 'http', backend: 'flask', engine: null }],
|
|
20
|
+
['http-fastapi', { architecture: 'http', backend: 'fastapi', engine: null }],
|
|
21
|
+
|
|
22
|
+
// Transformers architecture (5)
|
|
23
|
+
['transformers-vllm', { architecture: 'transformers', backend: 'vllm', engine: null }],
|
|
24
|
+
['transformers-sglang', { architecture: 'transformers', backend: 'sglang', engine: null }],
|
|
25
|
+
['transformers-tensorrt-llm', { architecture: 'transformers', backend: 'tensorrt-llm', engine: null }],
|
|
26
|
+
['transformers-lmi', { architecture: 'transformers', backend: 'lmi', engine: null }],
|
|
27
|
+
['transformers-djl', { architecture: 'transformers', backend: 'djl', engine: null }],
|
|
28
|
+
|
|
29
|
+
// Triton architecture (7)
|
|
30
|
+
['triton-fil', { architecture: 'triton', backend: 'fil', engine: null }],
|
|
31
|
+
['triton-onnxruntime', { architecture: 'triton', backend: 'onnxruntime', engine: null }],
|
|
32
|
+
['triton-tensorflow', { architecture: 'triton', backend: 'tensorflow', engine: null }],
|
|
33
|
+
['triton-pytorch', { architecture: 'triton', backend: 'pytorch', engine: null }],
|
|
34
|
+
['triton-vllm', { architecture: 'triton', backend: 'vllm', engine: null }],
|
|
35
|
+
['triton-tensorrtllm', { architecture: 'triton', backend: 'tensorrtllm', engine: null }],
|
|
36
|
+
['triton-python', { architecture: 'triton', backend: 'python', engine: null }],
|
|
37
|
+
|
|
38
|
+
// Diffusors architecture (1)
|
|
39
|
+
['diffusors-vllm-omni', { architecture: 'diffusors', backend: 'vllm-omni', engine: null }],
|
|
40
|
+
])
|
|
41
|
+
|
|
42
|
+
export default class DeploymentConfigResolver {
|
|
43
|
+
/**
|
|
44
|
+
* Decompose a deployment-config string into its constituent parts.
|
|
45
|
+
*
|
|
46
|
+
* @param {string} deploymentConfig - e.g. 'http-flask', 'transformers-vllm', 'triton-fil'
|
|
47
|
+
* @returns {{ architecture: string, backend: string, engine: string|null }}
|
|
48
|
+
* @throws {Error} if the deployment-config is not one of the 15 canonical values
|
|
49
|
+
*/
|
|
50
|
+
decompose(deploymentConfig) {
|
|
51
|
+
const parts = CANONICAL_CONFIGS.get(deploymentConfig)
|
|
52
|
+
if (!parts) {
|
|
53
|
+
const valid = this.getAllConfigs().join(', ')
|
|
54
|
+
throw new Error(
|
|
55
|
+
`Unsupported deployment-config: ${deploymentConfig}. Valid configs: ${valid}`
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
return { ...parts }
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Compose a deployment-config string from structured parts.
|
|
63
|
+
* Inverse of decompose().
|
|
64
|
+
*
|
|
65
|
+
* @param {{ architecture: string, backend: string, engine?: string }} parts
|
|
66
|
+
* @returns {string}
|
|
67
|
+
*/
|
|
68
|
+
compose(parts) {
|
|
69
|
+
return `${parts.architecture}-${parts.backend}`
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Get all 15 valid deployment-config strings.
|
|
74
|
+
*
|
|
75
|
+
* @returns {string[]}
|
|
76
|
+
*/
|
|
77
|
+
getAllConfigs() {
|
|
78
|
+
return [...CANONICAL_CONFIGS.keys()]
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Get valid deployment-config strings for a given architecture.
|
|
83
|
+
*
|
|
84
|
+
* @param {string} architecture - 'http' | 'transformers' | 'triton' | 'diffusors'
|
|
85
|
+
* @returns {string[]}
|
|
86
|
+
*/
|
|
87
|
+
getConfigsForArchitecture(architecture) {
|
|
88
|
+
return this.getAllConfigs().filter(
|
|
89
|
+
(dc) => CANONICAL_CONFIGS.get(dc).architecture === architecture
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Check if a deployment-config string is valid.
|
|
95
|
+
* Old-format strings (e.g. 'sklearn-flask') return false.
|
|
96
|
+
*
|
|
97
|
+
* @param {string} deploymentConfig
|
|
98
|
+
* @returns {boolean}
|
|
99
|
+
*/
|
|
100
|
+
isValid(deploymentConfig) {
|
|
101
|
+
return CANONICAL_CONFIGS.has(deploymentConfig)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON Schema for Deployment Entry
|
|
3
|
+
*
|
|
4
|
+
* Defines the structure and validation rules for deployment registry entries.
|
|
5
|
+
* Each entry captures the full configuration state and outcome of a single
|
|
6
|
+
* ML model deployment.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export default {
|
|
10
|
+
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
11
|
+
type: 'object',
|
|
12
|
+
required: [
|
|
13
|
+
'id',
|
|
14
|
+
'timestamp',
|
|
15
|
+
'status',
|
|
16
|
+
'deployment',
|
|
17
|
+
'model',
|
|
18
|
+
'infrastructure',
|
|
19
|
+
'configuration',
|
|
20
|
+
'outcome',
|
|
21
|
+
'metadata'
|
|
22
|
+
],
|
|
23
|
+
properties: {
|
|
24
|
+
id: {
|
|
25
|
+
type: 'string',
|
|
26
|
+
pattern: '^[0-9a-f]{8}$'
|
|
27
|
+
},
|
|
28
|
+
timestamp: {
|
|
29
|
+
type: 'string',
|
|
30
|
+
pattern: '^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(Z|[+-]\\d{2}:\\d{2})$'
|
|
31
|
+
},
|
|
32
|
+
status: {
|
|
33
|
+
type: 'string',
|
|
34
|
+
enum: ['success', 'partial', 'failed']
|
|
35
|
+
},
|
|
36
|
+
deployment: {
|
|
37
|
+
type: 'object',
|
|
38
|
+
required: ['deploymentConfig', 'architecture', 'backend'],
|
|
39
|
+
properties: {
|
|
40
|
+
deploymentConfig: {
|
|
41
|
+
type: 'string',
|
|
42
|
+
minLength: 1
|
|
43
|
+
},
|
|
44
|
+
architecture: {
|
|
45
|
+
type: 'string',
|
|
46
|
+
enum: ['http', 'transformers', 'triton', 'diffusors']
|
|
47
|
+
},
|
|
48
|
+
backend: {
|
|
49
|
+
type: 'string',
|
|
50
|
+
minLength: 1
|
|
51
|
+
},
|
|
52
|
+
baseImage: {
|
|
53
|
+
type: ['string', 'null']
|
|
54
|
+
},
|
|
55
|
+
deploymentTarget: {
|
|
56
|
+
type: ['string', 'null']
|
|
57
|
+
},
|
|
58
|
+
buildTarget: {
|
|
59
|
+
type: ['string', 'null']
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
model: {
|
|
64
|
+
type: 'object',
|
|
65
|
+
required: ['modelName'],
|
|
66
|
+
properties: {
|
|
67
|
+
modelName: {
|
|
68
|
+
type: 'string',
|
|
69
|
+
minLength: 1
|
|
70
|
+
},
|
|
71
|
+
modelFormat: {
|
|
72
|
+
type: ['string', 'null']
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
infrastructure: {
|
|
77
|
+
type: 'object',
|
|
78
|
+
properties: {
|
|
79
|
+
instanceType: {
|
|
80
|
+
type: ['string', 'null']
|
|
81
|
+
},
|
|
82
|
+
region: {
|
|
83
|
+
type: ['string', 'null']
|
|
84
|
+
},
|
|
85
|
+
roleArn: {
|
|
86
|
+
type: ['string', 'null']
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
configuration: {
|
|
91
|
+
type: 'object',
|
|
92
|
+
required: ['parameters'],
|
|
93
|
+
properties: {
|
|
94
|
+
parameters: {
|
|
95
|
+
type: 'object'
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
outcome: {
|
|
100
|
+
type: 'object',
|
|
101
|
+
properties: {
|
|
102
|
+
notes: {
|
|
103
|
+
type: ['string', 'null']
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
metadata: {
|
|
108
|
+
type: 'object',
|
|
109
|
+
required: ['generatorVersion', 'source'],
|
|
110
|
+
properties: {
|
|
111
|
+
generatorVersion: {
|
|
112
|
+
type: 'string',
|
|
113
|
+
minLength: 1
|
|
114
|
+
},
|
|
115
|
+
source: {
|
|
116
|
+
type: 'string',
|
|
117
|
+
enum: ['local', 'imported', 'community']
|
|
118
|
+
},
|
|
119
|
+
importedFrom: {
|
|
120
|
+
type: ['string', 'null']
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
};
|