Log directly with MLflow
Issuing an MLflow token to record training from a laptop or in-house server on the platform's experiment screens and model registry
Required permission: DevelopDEVELOPER · OPERATOR · ADMIN
The platform uses MLflow behind experiment tracking and the model registry. Training run outside the platform (laptops, in-house GPU servers, CI) can also be recorded on the platform with the standard MLflow Python client as is. You need only two things.
- Tracking address:
https://<platform address>/mlflow - An MLflow token — a token bound to a tenant. The token itself is the tenant boundary, so your code needs no tenant setting and no
X-Tenantheader
Experiments, runs and registered models recorded with a token are visible only in that token's tenant, and appear on the platform's Experiments (실험) and Model Registry (모델 레지스트리) screens as soon as they are recorded.
1. Issue a token — screen
- Go to the avatar at the top right → Account settings (계정 설정) → MLflow tokens (MLflow 토큰). DEVELOPER or higher can issue tokens.
- Set a token name (optional) and ③ the expiry in days, then press Issue (발급). ① The token is shown only this once. ② Copy the
exportcommands, already filled in with this server's tracking address, and use them as is.Right after issuing an MLflow token — ① the secret is shown once ② export commands with the tracking URI ③ expiry in days
In the list below, see when each token was issued, when it expires and when it was last used, and Revoke (회수) any token that may have leaked. Requests with a revoked token are rejected with 401. The training:… tokens in the list are ones the platform issued for each training run and revoked when the run ended.
1-b. Issue a token — API
Where you cannot use the screen, such as CI, issue one through the API.
API=https://mlops.example.com
JWT=$(curl -sS -X POST "$API/auth/jwt/login" \
--data-urlencode "username=you@example.com" \
--data-urlencode "password=<your-password>" | jq -r .access_token)
curl -sS -X POST "$API/api/v1/mlflow/tokens" \
-H "Authorization: Bearer $JWT" -H "X-Tenant: DEMO" \
-H 'Content-Type: application/json' \
-d '{"name": "ci-train", "expires_in_days": 30}'
{"id": "9d32c814-…", "token": "<secret>", "tenant": "DEMO", "workspace": "demo",
"tracking_uri": "https://mlops.example.com/mlflow"}
Leaving out expires_in_days gives a token with no expiry. Such a token stays valid until revoked, so use it only where you really need it.
2. Environment variables
export MLFLOW_TRACKING_URI=https://mlops.example.com/mlflow
export MLFLOW_TRACKING_TOKEN=<issued token>
Do not write the token in code or a repository; pass it through an environment variable or a secret management tool. To check the connection:
import mlflow
print(mlflow.get_tracking_uri())
for exp in mlflow.search_experiments(): # only this tenant's experiments are visible
print(exp.experiment_id, exp.name)
3. Record
Below is code actually recorded to the capture stack (MLflow 3.13.0). Outside the platform, you may name the experiment with set_experiment() — the ban applies only inside platform training containers.
import mlflow
import pandas as pd
from mlflow.models import infer_signature
mlflow.set_experiment("docs-mlflow-direct") # created if it does not exist
with mlflow.start_run(run_name="baseline") as run:
mlflow.log_params({"epochs": 3, "lr": 0.001})
for epoch in range(3):
mlflow.log_metrics({"train/loss": 1.0 / (epoch + 1),
"eval/accuracy": 0.5 + 0.1 * epoch}, step=epoch)
mlflow.log_text("hello", "notes/summary.txt") # any file as an artifact
class Echo(mlflow.pyfunc.PythonModel):
def predict(self, context, model_input, params=None):
return model_input
df = pd.DataFrame({"x": [1.0]})
info = mlflow.pyfunc.log_model(name="model", python_model=Echo(),
signature=infer_signature(df, df))
- If you pass
step, curves are drawn in the metrics tab of the run detail. - A recorded run shows up right away on the platform's Experiments (실험) screen.
4. Register in the model registry
| Method | Code | When |
|---|---|---|
| At logging time | mlflow.pyfunc.log_model(..., registered_model_name="mnist-cnn") | When you always register |
| Conditionally after logging | mlflow.register_model(info.model_uri, "mnist-cnn") | Register only when validation metrics pass a threshold |
| From the platform screen | Register model (모델 등록) in the run detail | Record in code, let a person decide on registration |
mv = mlflow.register_model(info.model_uri, "docs-mlflow-direct")
print(mv.name, mv.version) # docs-mlflow-direct 1
- Pass
info.model_uri(models:/m-…) returned bylog_model()toregister_model()as is. MLflow 3 keeps logged models outside the run artifacts, so guessingruns:/<run>/modelcan fail. - The old way — uploading only the weight file as an artifact and registering it with
MlflowClient().create_model_version(source="runs:/…/weights/best.pt")— does register. But withoutMLmodel, no serving image can be built. For a model that will go to deployment, keep it withpyfunc.log_model.
Stage
A version registered directly from code has the stage None (confirmed). A version automatically registered by platform training moves to Staging. Do not promote to Production through the API; use the promotion request → approval procedure on the platform screens. Promotion history must be kept as approval and audit records.
Troubleshooting
| Symptom | Cause and fix |
|---|---|
401 / 403 | The token is missing, expired or revoked. Check its status in MLflow tokens (MLflow 토큰) and issue a new one. Check that MLFLOW_TRACKING_TOKEN reaches the running process |
| Recorded, but not visible on screen | Recorded with a token of another tenant. Check that the tenant at token issue time matches the tenant on screen |
| Connection fails behind a corporate proxy | Add the platform host to NO_PROXY or check the HTTPS_PROXY setting |
| Artifact upload fails | Possibly a problem with the server's object storage connection. Tell the operator |