It claimed to run the pipeline with no engine involved, and could not: the node bodies it called save and load artifacts, which raise outside a node by design. Each node is now a thin wrapper over a plain function — make_rows, train_curve, score — and __main__ calls those, which is the split the sandbox already demonstrates and the one worth copying. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
25 lines
723 B
Python
25 lines
723 B
Python
"""Scoring what was trained."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
|
|
import fluksio
|
|
from fluksio import Port, node
|
|
|
|
|
|
def score(lr: float, epochs: int) -> float:
|
|
"""How good the model came out, with no Fluksio in it."""
|
|
return round(1 - lr / (1 + epochs), 4)
|
|
|
|
|
|
@node(requires=["weights"], provides=Port("score", "float"))
|
|
def evaluate(weights):
|
|
"""Score the model, returning the number rather than a dict.
|
|
|
|
`provides=Port(...)` — one port rather than a list of them — is the opt-in
|
|
to a bare return: the generated node wraps it in the message it belongs to.
|
|
"""
|
|
trained = json.loads(open(fluksio.load_artifact(weights)).read())
|
|
return score(trained["lr"], trained["epochs"])
|