fix(ml): align TFT feature counts with data pipeline + fix S3 path-style upload

TFT create_model used TFTConfig::default() values for num_known_features(10)
and num_unknown_features(210) totaling 220, but input_dim was 51 from the
feature extractor. Set both explicitly: known=0, unknown=feature_dim.

S3 uploader now uses path-style requests (required for Scaleway S3) and
explicitly passes AWS credentials from env vars instead of relying on the
instance metadata credential provider (unavailable on Kapsule).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
jgrusewski
2026-02-26 14:29:34 +01:00
parent 33a91b07c0
commit b07cc35f83
2 changed files with 19 additions and 2 deletions

View File

@@ -232,6 +232,8 @@ fn create_model(
num_layers: 2,
num_quantiles: 3,
num_static_features: 0,
num_known_features: 0,
num_unknown_features: feature_dim,
dropout_rate: hp_f64(hp, "dropout").unwrap_or(0.1),
..TFTConfig::default()
};

View File

@@ -113,11 +113,26 @@ fn read_metrics(dir: &Path) -> HashMap<String, f64> {
///
/// Uses an iterative stack-based directory walk to avoid async-recursion.
async fn upload_artifacts(args: &Args) -> Result<String> {
let store = AmazonS3Builder::new()
let mut builder = AmazonS3Builder::new()
.with_bucket_name(&args.s3_bucket)
.with_endpoint(&args.s3_endpoint)
.with_region(&args.s3_region)
.with_allow_http(false)
.with_virtual_hosted_style_request(false)
.with_allow_http(false);
// Explicitly pass credentials from env vars (Scaleway S3 has no instance metadata)
if let (Ok(key_id), Ok(secret)) = (
std::env::var("AWS_ACCESS_KEY_ID"),
std::env::var("AWS_SECRET_ACCESS_KEY"),
) {
builder = builder
.with_access_key_id(key_id)
.with_secret_access_key(secret);
} else {
warn!("AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY not set — S3 upload may fail");
}
let store = builder
.build()
.context("Failed to build S3 client")?;