Skip to content

training::train_specialists_mlx

More...

Functions

Name
str prepare_dataset_for_mlx(str niche_name)
SimpleNamespace build_args_for_niche(str niche_name, str base_model, str data_dir, str adapter_path)
train_specialist(str niche_name)
main()

Attributes

Name
PROJECT_ROOT
dict SPECIALIST_BASE_MODELS
SPECIALISTS
DATA_DIR
OUTPUT_DIR
parents
True
exist_ok
dict OVERRIDES

Detailed Description

Train GNUS.ai specialist models using mlx-lm's internal LoRA trainer.

Specialists:
  - medical        -> mlx-community/Qwen3-30B-A3B-Instruct-2507-bf16
  - qa_technical   -> mlx-community/Qwen3-30B-A3B-Instruct-2507-bf16
  - code           -> mlx-community/Qwen3-Coder-30B-A3B-Instruct-bf16
  - encyclopedic   -> mlx-community/Qwen3-30B-A3B-Instruct-2507-bf16
  - patents        -> mlx-community/Qwen3-30B-A3B-Instruct-2507-bf16

Data:
  - data/specialists/<niche> (HF datasets saved with save_to_disk)
  - This script converts each to:
      data/specialists/<niche>_mlx/{train,valid}.jsonl
    with {"text": "..."} lines as mlx-lm docs specify.

Pipeline (per specialist):
  - Build args from mlx_lm.lora.CONFIG_DEFAULTS + overrides
  - mlx_lm.utils.load(model_id) -> model, tokenizer
  - mlx_lm.tuner.datasets.load_dataset(args, tokenizer) -> train/val/test
  - mlx_lm.lora.train_model(args, model, train_set, valid_set)

Functions Documentation

function prepare_dataset_for_mlx

str prepare_dataset_for_mlx(
    str niche_name
)
Convert HF dataset (save_to_disk) into MLX-LM JSONL format:
  data/specialists/<niche>_mlx/{train,valid}.jsonl

Each line: {"text": "..."}  (mlx-lm LORA.md 'text' format).

function build_args_for_niche

SimpleNamespace build_args_for_niche(
    str niche_name,
    str base_model,
    str data_dir,
    str adapter_path
)
Build args namespace exactly like mlx_lm.lora.run() would,
but we call train_model() directly instead of run().

function train_specialist

train_specialist(
    str niche_name
)

function main

main()

Attributes Documentation

variable PROJECT_ROOT

PROJECT_ROOT =  Path(__file__).resolve().parent.parent;

variable SPECIALIST_BASE_MODELS

dict SPECIALIST_BASE_MODELS =  {
    "medical":      "mlx-community/Qwen3-30B-A3B-Instruct-2507-bf16",
    "qa_technical": "mlx-community/Qwen3-30B-A3B-Instruct-2507-bf16",
    "code":         "mlx-community/Qwen3-Coder-30B-A3B-Instruct-bf16",
    "encyclopedic": "mlx-community/Qwen3-30B-A3B-Instruct-2507-bf16",
    "patents":      "mlx-community/Qwen3-30B-A3B-Instruct-2507-bf16",
};

variable SPECIALISTS

SPECIALISTS =  list(SPECIALIST_BASE_MODELS.keys());

variable DATA_DIR

DATA_DIR =  str(PROJECT_ROOT / "data" / "specialists");

variable OUTPUT_DIR

OUTPUT_DIR =  str(PROJECT_ROOT / "models" / "specialists_mlx");

variable parents

parents;

variable True

True;

variable exist_ok

exist_ok;

variable OVERRIDES

dict OVERRIDES =  {
    "fine_tune_type": "lora",    # LoRA/QLoRA
    "optimizer": "adamw",
    "batch_size": 4,
    "iters": 1000,               # drop to 200–400 while testing if needed
    "val_batches": 25,
    "learning_rate": 1e-5,
    "steps_per_report": 50,
    "steps_per_eval": 200,
    "save_every": 200,
    "num_layers": 16,            # how many layers to LoRA-ize (see docs)
    "grad_checkpoint": True,
    "grad_accumulation_steps": 1,
    "mask_prompt": False,
    "report_to": None,
    "project_name": None,
    "seed": 42,
    "lora_parameters": {
        "rank": 16,
        "dropout": 0.05,
        "scale": 20.0,
    },
};

Updated on 2026-07-25 at 22:56:57 +0000