# strands-mlx
[](https://pypi.org/project/strands-mlx/)
[](https://github.com/cagataycali/strands-mlx/actions/workflows/agent.yml)
**Running Strands Agents locally on Apple Silicon - inference, fine-tuning, vision in Python**
MLX provider for [Strands Agents](https://strandsagents.com) with LoRA training pipelines.
---
**Requirements:** Python ≤3.13, macOS/Linux
```bash
# Text models
pip install strands-mlx
# With vision/audio/video
pip install "strands-mlx[vision]"
# Environment setup
uv venv --python 3.13 && source .venv/bin/activate
# Install dependencies
uv pip install strands-agents strands-mlx strands-agents-tools
```
---
## Quick Start
agent.py
```python
from strands import Agent
from strands_mlx import MLXModel
from strands_tools import calculator
model = MLXModel(model_id="mlx-community/Qwen3-1.7B-4bit")
agent = Agent(model=model, tools=[calculator])
agent("What is 29 * 42?")
```
```bash
# Run with uv
uv run agent.py
```
---
## Architecture
```mermaid
graph LR
    A[Agent Conversations] -->|MLXSessionManager| B[Training Data JSONL]
    B -->|dataset_splitter| C[train/valid/test]
    C -->|mlx_trainer| D[LoRA Adapter]
    D -->|MLXModel| E[Domain Expert Agent]
    E -.->|Continuous Learning| A
    
    style A fill:#e1f5ff
    style E fill:#d4edda
    style D fill:#fff3cd
```
**The complete training cycle:** Agents collect their own training data → fine-tune themselves → become domain experts → continue learning.
---
## Train Your Own Model
**4 steps: Collect → Split → Train → Use**
### 1. Collect Training Data
```python
from strands import Agent
from strands_tools import calculator
from strands_mlx import MLXSessionManager, dataset_splitter, mlx_trainer
session = MLXSessionManager(session_id="my_training", storage_dir="./dataset")
agent = Agent(model=model, tools=[calculator, dataset_splitter, mlx_trainer], session_manager=session)
# Have conversations - auto-saved to JSONL
agent("Teach me about quantum computing")
agent("Calculate 15 * 7")
# Saved to: ./dataset/my_training.jsonl
```
### 2. Split Dataset
```python
agent.tool.dataset_splitter(
    input_path="./dataset/my_training.jsonl"
)
# Creates train.jsonl, valid.jsonl, test.jsonl (80/10/10 split)
```
### 3. Train with LoRA
```python
agent.tool.mlx_trainer(
    action="train",
    config={
        "model": "mlx-community/Qwen3-1.7B-4bit",
        "data": "./dataset/my_training",
        "adapter_path": "./adapter",
        "iters": 200,
        "learning_rate": 1e-5,
        "batch_size": 1
    }
)
```
### 4. Use Trained Model
```python
from strands import Agent
from strands_mlx import MLXModel
trained = MLXModel("mlx-community/Qwen3-1.7B-4bit", adapter_path="./adapter")
agent = Agent(model=trained)
agent("Explain quantum computing")  # Uses trained knowledge!
```
---
## Vision Models
```python
from strands_mlx import MLXVisionModel
model = MLXVisionModel(model_id="mlx-community/Qwen2-VL-2B-Instruct-4bit")
agent = Agent(model=model)
agent("Describe: <image>photo.jpg</image>")
agent("Transcribe: <audio>speech.wav</audio>")
agent("What happens: <video>clip.mp4</video>")
```
---
## Training Tools
| Tool | Purpose |
|------|---------|
| `mlx_trainer` | Background LoRA training |
| `dataset_splitter` | Split JSONL → train/valid/test |
| `validate_training_data` | Check format & token counts |
| `mlx_invoke` | Runtime model switching |
| `mlx_vision_invoke` | Vision as a tool |
---
## Advanced Training
**YAML config file:**
```yaml
model: mlx-community/Qwen3-1.7B-4bit
data: ./training_data
iters: 1000
learning_rate: 1e-5
lora_parameters:
  rank: 8
  scale: 16.0
lr_schedule:
  name: cosine_decay
  warmup: 100
optimizer: adamw
```
**Use config:**
```python
agent.tool.mlx_trainer(action="train", config="./lora_config.yaml")
```
---
## Popular Models
**Text:**
- `mlx-community/Qwen3-1.7B-4bit` (recommended)
- `mlx-community/Qwen3-4B-4bit`
- `mlx-community/Llama-3.2-1B-4bit`
- `mlx-community/gemma-2-2b-it-4bit`
**Vision:**
- `mlx-community/Qwen2-VL-2B-Instruct-4bit` (recommended)
- `mlx-community/Qwen2-Audio-7B-Instruct` (audio)
- `mlx-community/llava-v1.6-mistral-7b-4bit`
[Community models at mlx-community](https://huggingface.co/mlx-community)
---
## Troubleshooting
**Out of memory:**
```python
config = {
    "grad_checkpoint": True,
    "batch_size": 1,
    "max_seq_length": 1024
}
```
**Model degraded:**
```python
config = {
    "iters": 200,  # Lower for small datasets
    "learning_rate": 1e-5  # Conservative
}
```
---
## Resources
- [Strands Agents](https://strandsagents.com)
- [MLX](https://ml-explore.github.io/mlx/)
- [mlx-community models](https://huggingface.co/mlx-community)
---
## Citation
```bibtex
@software{strands_mlx2025,
  author = {Cagatay Cali},
  title = {strands-mlx: MLX Model Provider for Strands Agents},
  year = {2025},
  url = {https://github.com/cagataycali/strands-mlx}
}
```
**Apache 2 License** | Built with MLX, MLX-LM, and Strands Agents
            
         
        Raw data
        
            {
    "_id": null,
    "home_page": null,
    "name": "strands-mlx",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<3.14,>=3.10",
    "maintainer_email": null,
    "keywords": "strands, agents, fine-tuning, lora, llm, mlx-lm",
    "author": null,
    "author_email": "Cagatay Cali <cagataycali@icloud.com>",
    "download_url": "https://files.pythonhosted.org/packages/b2/86/41584c77def11667cdafd94eed007b2fde57c07cecca23aad4f72d25c7c1/strands_mlx-0.2.6.tar.gz",
    "platform": null,
    "description": "# strands-mlx\n\n[](https://pypi.org/project/strands-mlx/)\n[](https://github.com/cagataycali/strands-mlx/actions/workflows/agent.yml)\n\n**Running Strands Agents locally on Apple Silicon - inference, fine-tuning, vision in Python**\n\nMLX provider for [Strands Agents](https://strandsagents.com) with LoRA training pipelines.\n\n---\n\n**Requirements:** Python \u22643.13, macOS/Linux\n\n```bash\n# Text models\npip install strands-mlx\n\n# With vision/audio/video\npip install \"strands-mlx[vision]\"\n\n# Environment setup\nuv venv --python 3.13 && source .venv/bin/activate\n\n# Install dependencies\nuv pip install strands-agents strands-mlx strands-agents-tools\n```\n\n---\n\n## Quick Start\n\nagent.py\n\n```python\nfrom strands import Agent\nfrom strands_mlx import MLXModel\nfrom strands_tools import calculator\n\nmodel = MLXModel(model_id=\"mlx-community/Qwen3-1.7B-4bit\")\nagent = Agent(model=model, tools=[calculator])\n\nagent(\"What is 29 * 42?\")\n```\n\n```bash\n# Run with uv\nuv run agent.py\n```\n\n---\n\n## Architecture\n\n```mermaid\ngraph LR\n    A[Agent Conversations] -->|MLXSessionManager| B[Training Data JSONL]\n    B -->|dataset_splitter| C[train/valid/test]\n    C -->|mlx_trainer| D[LoRA Adapter]\n    D -->|MLXModel| E[Domain Expert Agent]\n    E -.->|Continuous Learning| A\n    \n    style A fill:#e1f5ff\n    style E fill:#d4edda\n    style D fill:#fff3cd\n```\n\n**The complete training cycle:** Agents collect their own training data \u2192 fine-tune themselves \u2192 become domain experts \u2192 continue learning.\n\n---\n\n## Train Your Own Model\n\n**4 steps: Collect \u2192 Split \u2192 Train \u2192 Use**\n\n### 1. Collect Training Data\n\n```python\nfrom strands import Agent\nfrom strands_tools import calculator\nfrom strands_mlx import MLXSessionManager, dataset_splitter, mlx_trainer\n\nsession = MLXSessionManager(session_id=\"my_training\", storage_dir=\"./dataset\")\nagent = Agent(model=model, tools=[calculator, dataset_splitter, mlx_trainer], session_manager=session)\n\n# Have conversations - auto-saved to JSONL\nagent(\"Teach me about quantum computing\")\nagent(\"Calculate 15 * 7\")\n\n# Saved to: ./dataset/my_training.jsonl\n```\n\n### 2. Split Dataset\n\n```python\nagent.tool.dataset_splitter(\n    input_path=\"./dataset/my_training.jsonl\"\n)\n# Creates train.jsonl, valid.jsonl, test.jsonl (80/10/10 split)\n```\n\n### 3. Train with LoRA\n\n```python\nagent.tool.mlx_trainer(\n    action=\"train\",\n    config={\n        \"model\": \"mlx-community/Qwen3-1.7B-4bit\",\n        \"data\": \"./dataset/my_training\",\n        \"adapter_path\": \"./adapter\",\n        \"iters\": 200,\n        \"learning_rate\": 1e-5,\n        \"batch_size\": 1\n    }\n)\n```\n\n### 4. Use Trained Model\n\n```python\nfrom strands import Agent\nfrom strands_mlx import MLXModel\n\ntrained = MLXModel(\"mlx-community/Qwen3-1.7B-4bit\", adapter_path=\"./adapter\")\nagent = Agent(model=trained)\n\nagent(\"Explain quantum computing\")  # Uses trained knowledge!\n```\n\n---\n\n## Vision Models\n\n```python\nfrom strands_mlx import MLXVisionModel\n\nmodel = MLXVisionModel(model_id=\"mlx-community/Qwen2-VL-2B-Instruct-4bit\")\nagent = Agent(model=model)\n\nagent(\"Describe: <image>photo.jpg</image>\")\nagent(\"Transcribe: <audio>speech.wav</audio>\")\nagent(\"What happens: <video>clip.mp4</video>\")\n```\n\n---\n\n## Training Tools\n\n| Tool | Purpose |\n|------|---------|\n| `mlx_trainer` | Background LoRA training |\n| `dataset_splitter` | Split JSONL \u2192 train/valid/test |\n| `validate_training_data` | Check format & token counts |\n| `mlx_invoke` | Runtime model switching |\n| `mlx_vision_invoke` | Vision as a tool |\n\n---\n\n## Advanced Training\n\n**YAML config file:**\n\n```yaml\nmodel: mlx-community/Qwen3-1.7B-4bit\ndata: ./training_data\niters: 1000\nlearning_rate: 1e-5\nlora_parameters:\n  rank: 8\n  scale: 16.0\nlr_schedule:\n  name: cosine_decay\n  warmup: 100\noptimizer: adamw\n```\n\n**Use config:**\n\n```python\nagent.tool.mlx_trainer(action=\"train\", config=\"./lora_config.yaml\")\n```\n\n---\n\n## Popular Models\n\n**Text:**\n- `mlx-community/Qwen3-1.7B-4bit` (recommended)\n- `mlx-community/Qwen3-4B-4bit`\n- `mlx-community/Llama-3.2-1B-4bit`\n- `mlx-community/gemma-2-2b-it-4bit`\n\n**Vision:**\n- `mlx-community/Qwen2-VL-2B-Instruct-4bit` (recommended)\n- `mlx-community/Qwen2-Audio-7B-Instruct` (audio)\n- `mlx-community/llava-v1.6-mistral-7b-4bit`\n\n[Community models at mlx-community](https://huggingface.co/mlx-community)\n\n---\n\n## Troubleshooting\n\n**Out of memory:**\n```python\nconfig = {\n    \"grad_checkpoint\": True,\n    \"batch_size\": 1,\n    \"max_seq_length\": 1024\n}\n```\n\n**Model degraded:**\n```python\nconfig = {\n    \"iters\": 200,  # Lower for small datasets\n    \"learning_rate\": 1e-5  # Conservative\n}\n```\n\n---\n\n## Resources\n\n- [Strands Agents](https://strandsagents.com)\n- [MLX](https://ml-explore.github.io/mlx/)\n- [mlx-community models](https://huggingface.co/mlx-community)\n\n---\n\n## Citation\n\n```bibtex\n@software{strands_mlx2025,\n  author = {Cagatay Cali},\n  title = {strands-mlx: MLX Model Provider for Strands Agents},\n  year = {2025},\n  url = {https://github.com/cagataycali/strands-mlx}\n}\n```\n\n**Apache 2 License** | Built with MLX, MLX-LM, and Strands Agents\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Use MLX in Strands Agents",
    "version": "0.2.6",
    "project_urls": {
        "Homepage": "https://github.com/cagataycali/strands-mlx",
        "Issues": "https://github.com/cagataycali/strands-mlx/issues",
        "Repository": "https://github.com/cagataycali/strands-mlx"
    },
    "split_keywords": [
        "strands",
        " agents",
        " fine-tuning",
        " lora",
        " llm",
        " mlx-lm"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "0e1a581860db4547e8db66ca33c4afe379c465bfe0cf4a4969c3a942f4c244ed",
                "md5": "6775c22d964a5c0bc50e0865f149da19",
                "sha256": "dc62b12d90e3c8ff2994a91d19d6bface2cd20fb4d23215a8548666faac4c869"
            },
            "downloads": -1,
            "filename": "strands_mlx-0.2.6-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "6775c22d964a5c0bc50e0865f149da19",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<3.14,>=3.10",
            "size": 44615,
            "upload_time": "2025-11-03T05:09:09",
            "upload_time_iso_8601": "2025-11-03T05:09:09.517091Z",
            "url": "https://files.pythonhosted.org/packages/0e/1a/581860db4547e8db66ca33c4afe379c465bfe0cf4a4969c3a942f4c244ed/strands_mlx-0.2.6-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "b28641584c77def11667cdafd94eed007b2fde57c07cecca23aad4f72d25c7c1",
                "md5": "384e0e98c65641ba16898d5a0d520010",
                "sha256": "4c0b230f26aedf6aef2f49ebfaf7c6cc82b89725bad71452ad81df91e5cfb83a"
            },
            "downloads": -1,
            "filename": "strands_mlx-0.2.6.tar.gz",
            "has_sig": false,
            "md5_digest": "384e0e98c65641ba16898d5a0d520010",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<3.14,>=3.10",
            "size": 42935,
            "upload_time": "2025-11-03T05:09:10",
            "upload_time_iso_8601": "2025-11-03T05:09:10.793705Z",
            "url": "https://files.pythonhosted.org/packages/b2/86/41584c77def11667cdafd94eed007b2fde57c07cecca23aad4f72d25c7c1/strands_mlx-0.2.6.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-11-03 05:09:10",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "cagataycali",
    "github_project": "strands-mlx",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "strands-agents",
            "specs": []
        },
        {
            "name": "mlx-lm",
            "specs": []
        },
        {
            "name": "mlx-vlm",
            "specs": []
        }
    ],
    "lcname": "strands-mlx"
}