Docs Changelog

Changelog

0.3.1 — 2026-06-30

Competitive positioning and public-site upgrade.

  • New kynml.competitors module with checked-in profiles for PyTorch Lightning, Keras, Ludwig, and ZenML.
  • New kynml compare [--focus name] [--format table|markdown|json] command.
  • New Competitive Map docs page.
  • Public homepage now includes a competitive map section and reflects the eight-command CLI surface.

0.3.0 — 2026-06-29

Phase 0/1 compiler upgrade: typed IR, shape inference, composition (params/import/sweep), reproducibility, formatter, and LSP diagnostics.

Breaking / Strictness

Shape inference runs at compile time (not at validate). Programs that previously passed kynml validate may now fail at kynml compile or kynml train if:

  • bce loss: the final dense layer does not have exactly 1 output unit. Previously accepted; now raises KynMLShapeError.
  • cross_entropy or nll loss: the final dense layer has fewer than 2 output units. Previously accepted; now raises KynMLShapeError.

Migration: ensure your last dense layer matches the loss. For bce use dense 1 sigmoid; for cross_entropy use dense N linear where N is your class count.

Programs using cross_entropy with a softmax or log_softmax activation on the final layer now emit a warning (not an error) at compile time. The warning is surfaced as a severity="warning" diagnostic in the LSP and printed to stderr by the CLI. This is not a breaking change, but the generated model will produce incorrect results — switch to dense N linear with cross_entropy.

Typed IR + Shape Inference

  • New package kynml/ir/: types.py, nodes.py, builder.py, infer.py, passes.py
  • TypeShape and DType primitives — static tensor types with a dynamic batch axis (None)
  • IRModule, IRGraph, IRTrain, IRDataset, IREvaluate, IRExport — frozen IR dataclasses
  • Layer IR ops: InputOp, LinearOp, DropoutOp, BatchNorm1dOp
  • lower_program(program) -> IRModule — pure structural translation from AST; inferred=False at this stage
  • infer_module(module) -> IRModule — threads TypeShape through each graph op sequence; fills LinearOp.in_features and BatchNorm1dOp.num_features automatically; raises KynMLShapeError on mismatches
  • run_passes(module) -> IRModule — pass registry (currently runs infer_module)
  • compile_to_ir(program, source_path, overrides) -> IRModule in kynml/pipeline.py — canonical front door: compose → validate → lower → infer
  • New error type: KynMLShapeError (subclass of KynMLSemanticError)

Users no longer need to specify in_features anywhere. The parser, AST, and semantic validator are unchanged for existing programs.

Backend Seam

  • New kynml/codegen/base.py: Backend ABC, EmitContext, get_backend(name)
  • New kynml/codegen/pytorch_backend.py: PyTorchBackend — reads exclusively from IRModule; asserts module.inferred at entry
  • kynml/codegen/pytorch.py is now a compatibility shim; generate_pytorch() and write_pytorch() have unchanged signatures and emitted-string contracts
  • Existing code importing generate_pytorch / write_pytorch requires no changes

Composition

  • New params: block — name = value pairs; any block can reference values via $name
  • New import "other.kyn" statements — merges dataset and model blocks; cycle detection; duplicate-name errors raise KynMLSemanticError
  • New sweep: block — each axis maps a param name to a list of values; grid expansion is Cartesian
  • kynml/compose.py: apply_composition(), resolve_imports(), substitute_params()
  • kynml/sweep.py: expand_sweep(), generate_sweep_runner()
  • ParamRef, ParamsBlock, SweepBlock added to ast_nodes.py
  • Program gains params, sweep, and imports fields (all default to None / [] — no breakage for existing programs)

Syntax examples:

params:
    hidden = 64
    lr = 0.001

sweep:
    lr = [0.001, 0.01]
    hidden = [32, 64]

import "shared/base.kyn"

model M:
    input 4
    dense $hidden relu
    dense 1 linear

train:
    optimizer = adam(lr=$lr)
    epochs = 20
    batch = $bs

CLI override: kynml compile model.kyn --out out.py --param lr=0.005 --param hidden=128

Reproducibility

  • seed and deterministic fields added to train: block
  • Generated scripts emit CONFIG_HASH (sha256 of the .kyn source, computed at codegen time), SEED, and _set_seed() covering random, numpy, torch, and torch.cuda
  • deterministic = true additionally sets torch.use_deterministic_algorithms(True) and torch.backends.cudnn.deterministic = True
  • Every generated script writes run_manifest.json after training: kynml_version, config_hash, data_hash (sha256 of the dataset, computed at runtime), env (python/torch/numpy/platform versions), seed, metrics
  • New kynml/repro/manifest.py: RunManifest, config_hash(), data_hash(), env_info(), write_manifest(), load_manifest()
  • New kynml/lock.py: create_lock(), check_lock(), read_lock(), LockMismatchError — opt-in config-hash pinning for drift detection
train:
    seed = 42
    deterministic = true

Formatter (kynml fmt)

  • New subcommand kynml fmt <file> [--write | --check]
  • --write overwrites the file in place; --check exits with code 1 if the file would change (CI-friendly)
  • Without flags, prints formatted source to stdout
  • python -m kynml.format <file> — equivalent module entry point
  • from kynml.format.formatter import format_source, format_file — Python API
  • Idempotent: format_source(format_source(x)) == format_source(x)
  • Rules: 4-space indentation, one blank line between blocks, no trailing whitespace, single trailing newline, canonical key order per block

LSP Diagnostics (kynml lsp)

  • New subcommand kynml lsp — starts an LSP server over stdio; requires pip install 'kynml[lsp]'
  • python -m kynml.lsp — equivalent module entry point
  • from kynml.lsp.diagnostics import diagnose — pure diagnostics API, no pygls required
  • diagnose(source) -> list[Diagnostic] — never raises; runs parse → validate → lower → infer; returns Diagnostic TypedDicts with line, col, severity ("error" | "warning"), message, code ("parse" | "semantic" | "shape" | "warn")
  • Shape errors and activation-footgun warnings from the inference pass are included

CLI Additions

New command Description
kynml sweep <file> [--out-dir dir] [--no-run] Expand sweep block, compile all combos, run orchestrator; writes sweep_results.json
kynml fmt <file> [--write] [--check] Format .kyn in canonical form
kynml lsp Start LSP server over stdio

kynml compile and kynml train accept --param key=value (repeatable) to override params block defaults.


0.2.0 — 2026-06-29

20x expansion of the language surface, CONNECT integrations, and tooling layer.

Language

  • New activations: leaky_relu (→ nn.LeakyReLU()), gelu (→ nn.GELU()), softmax (→ nn.Softmax(dim=1)), log_softmax (→ nn.LogSoftmax(dim=1)) alongside existing relu, sigmoid, tanh, linear
  • New losses: huber (→ nn.HuberLoss()), l1 / mae (→ nn.L1Loss()), nll (→ nn.NLLLoss()) alongside mse, bce, cross_entropy
  • New optimizers: adamw(lr, weight_decay), rmsprop(lr, momentum) alongside adam, sgd
  • New layer types: dropout P, batchnorm [N] — dropout rate validated in [0, 1), batchnorm infers feature count from prior layer
  • Schedulers: step(step_size, gamma), cosine(t_max), onecycle(max_lr) — emitted as full build_scheduler() functions in the generated script
  • Early stopping: early_stop(patience=N, mode="min"|"max") — tracks best epoch loss, breaks training loop on exhausted patience
  • Checkpointing: checkpoint(every_n=N, path="...", async_save=true|false) — saves {epoch, model, optimizer} state dicts, auto-resumes on next run
  • Mixed precision: precision = fp16 | bf16 — emits torch.amp.autocast + GradScaler with CUDA-availability guard
  • Graph compilation: compile = true — emits torch.compile(model) (requires PyTorch ≥ 2.0)
  • DataLoader controls: num_workers, pin_memory, prefetch on dataset block map directly to DataLoader kwargs
  • TorchScript export: format = torchscript via torch.jit.script; alongside existing torch (state dict) and onnx
  • ONNX opset: opset field on export block (default 17)

CONNECT — Serving

  • New sub-package kynml.serving
  • generate_service(program, model_path, out_dir) emits three files: app.py (FastAPI with /predict and /health), requirements.txt, Dockerfile
  • Optional extra: pip install 'kynml[serving]'

CONNECT — MCP

  • New sub-package kynml.mcp
  • python -m kynml.mcp.server runs a stdio MCP server
  • Four tools: kynml_validate, kynml_compile, kynml_train, kynml_predict
  • Optional extra: pip install 'kynml[mcp]'

CONNECT — Integrations

  • New sub-package kynml.integrations
  • kynml.integrations.huggingface.load_hf_dataset(dataset_id, split, target) — loads any HuggingFace Hub dataset as a pandas DataFrame
  • kynml.integrations.objectstore.load_remote(uri) — Parquet loading from s3://, r2://, or local .parquet paths
  • Optional extras: pip install 'kynml[hf]' and 'kynml[objectstore]'

Codegen

  • Multiclass detection: cross_entropy loss automatically switches the generated script to long target dtype and argmax-based metric evaluation
  • AMP fallback: precision = fp16 | bf16 generates a runtime torch.cuda.is_available() guard
  • Async checkpointing: async_save = true dispatches each checkpoint save on a daemon thread
  • Dataset path resolution: project root takes priority over .kyn file directory; both are tried before raising

Test Suite

  • 83 tests, all green

pyproject.toml

  • New optional extras: serving, mcp, hf, objectstore, all

0.1.0 — Initial Release

  • PyTorch transpiler MVP
  • CSV datasets, normalize, split, shuffle
  • Dense models: input, dense with relu, sigmoid, tanh, linear
  • Losses: mse, bce, cross_entropy
  • Optimizers: adam, sgd
  • Scheduler: cosine annealing
  • Metrics: mae, mse, rmse, accuracy
  • Export: torch (state dict), onnx
  • CLI: validate, ast, compile, train
  • Static site on Cloudflare Pages at kynml.kynetra.dev