slicktune 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,166 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ .ruff_cache/
6
+
7
+ # C extensions
8
+ *.so
9
+
10
+ # Distribution / packaging
11
+ .Python
12
+ build/
13
+ develop-eggs/
14
+ dist/
15
+ downloads/
16
+ eggs/
17
+ .eggs/
18
+ lib/
19
+ lib64/
20
+ parts/
21
+ sdist/
22
+ var/
23
+ wheels/
24
+ share/python-wheels/
25
+ *.egg-info/
26
+ .installed.cfg
27
+ *.egg
28
+ MANIFEST
29
+
30
+ # PyInstaller
31
+ *.manifest
32
+ *.spec
33
+
34
+ # Installer logs
35
+ pip-log.txt
36
+ pip-delete-this-directory.txt
37
+
38
+ # Unit test / coverage reports
39
+ htmlcov/
40
+ xmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py,cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ .python-version
87
+
88
+ # pipenv
89
+ Pipfile.lock
90
+
91
+ # poetry
92
+ poetry.lock
93
+
94
+ # pdm
95
+ .pdm.toml
96
+
97
+ # PEP 582
98
+ __pypackages__/
99
+
100
+ # Celery stuff
101
+ celerybeat-schedule
102
+ celerybeat.pid
103
+
104
+ # SageMath parsed files
105
+ *.sage.py
106
+
107
+ # Environments
108
+ .env
109
+ .venv
110
+ env/
111
+ venv/
112
+ ENV/
113
+ env.bak/
114
+ venv.bak/
115
+
116
+ # Spyder project settings
117
+ .spyderproject
118
+ .spyproject
119
+
120
+ # Rope project settings
121
+ .ropeproject
122
+
123
+ # mkdocs documentation
124
+ /site
125
+
126
+ # mypy
127
+ .mypy_cache/
128
+ .dmypy.json
129
+ dmypy.json
130
+
131
+ # Pyre type checker
132
+ .pyre/
133
+
134
+ # pytype static type analyzer
135
+ .pytype/
136
+
137
+ # Cython debug symbols
138
+ cython_debug/
139
+
140
+ # IDEs
141
+ .vscode/
142
+ .idea/
143
+ *.swp
144
+ *.swo
145
+ *~
146
+ .DS_Store
147
+
148
+
149
+ # Environment variables
150
+ .env.local
151
+ .env.*.local
152
+
153
+ # OS files
154
+ .DS_Store
155
+ .DS_Store?
156
+ ._*
157
+ .Spotlight-V100
158
+ .Trashes
159
+ ehthumbs.db
160
+ Thumbs.db
161
+ # slick-tune local artifacts
162
+ .venv/
163
+ outputs/
164
+ *.pt
165
+ *.bin
166
+ *.safetensors
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 SlickML
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,227 @@
1
+ Metadata-Version: 2.4
2
+ Name: slicktune
3
+ Version: 0.1.0
4
+ Summary: SlickML fine-tuning toolkit: composable strategies, objectives, and metrics for LLMs
5
+ Project-URL: Homepage, https://www.slickml.com
6
+ Project-URL: Repository, https://github.com/slickml/slick-tune
7
+ Author-email: Amirhessam Tahmassebi <admin@slickml.com>
8
+ License: MIT
9
+ License-File: LICENSE
10
+ Keywords: fine-tuning,llm,lora,machine-learning,peft,qlora,sft
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Typing :: Typed
20
+ Requires-Python: <3.13,>=3.10
21
+ Requires-Dist: accelerate>=0.34
22
+ Requires-Dist: click>=8.1
23
+ Requires-Dist: datasets>=3.0
24
+ Requires-Dist: peft>=0.12
25
+ Requires-Dist: rich>=13.0
26
+ Requires-Dist: sentencepiece>=0.2
27
+ Requires-Dist: torch>=2.2
28
+ Requires-Dist: transformers>=4.44
29
+ Requires-Dist: trl>=0.12
30
+ Provides-Extra: dev
31
+ Requires-Dist: assertpy>=1.1; extra == 'dev'
32
+ Requires-Dist: mypy>=2.3.0; extra == 'dev'
33
+ Requires-Dist: pytest-cov>=5.0; extra == 'dev'
34
+ Requires-Dist: pytest>=8.3; extra == 'dev'
35
+ Requires-Dist: ruff>=0.6; extra == 'dev'
36
+ Provides-Extra: qlora
37
+ Requires-Dist: bitsandbytes>=0.43; extra == 'qlora'
38
+ Description-Content-Type: text/markdown
39
+
40
+ <p align="center">
41
+ <img src="assets/design/logo.png" alt="slick-tune logo" width="420"/>
42
+ </p>
43
+
44
+ # SlickTune 🧩: Composable LLM fine-tuning by [SlickML](https://github.com/slickml)
45
+
46
+
47
+ Fine-tuning is an orthogonal stack β€” swap any axis without rewriting the others:
48
+
49
+ ```text
50
+ model Γ— strategy Γ— objective Γ— data Γ— metrics
51
+ ```
52
+
53
+ ## 🧠 Philosophy
54
+
55
+ **slick-tune** is a small, composable toolkit for teaching LLMs new facts and behaviors with
56
+ [Transformers](https://huggingface.co/docs/transformers) + [PEFT](https://huggingface.co/docs/peft) + [TRL](https://huggingface.co/docs/trl).
57
+ LoRA / QLoRA are PEFT adapters; full FT updates every weight. The goal is the same SlickML spirit:
58
+ prototype fast 🏎, keep axes orthogonal, and measure whether the model actually learned *your* facts πŸ”Ž.
59
+
60
+ ## 🧩 Abstractions
61
+
62
+ ```mermaid
63
+ flowchart TB
64
+ subgraph inputs [Inputs]
65
+ modelId[model_id]
66
+ dataJsonl[data JSONL]
67
+ end
68
+
69
+ subgraph axes [Composable axes]
70
+ strategyNode["Strategy: LoRA / QLoRA / Full"]
71
+ objectiveNode["Objective: SFT then DPO / GRPO"]
72
+ end
73
+
74
+ subgraph core [Tuner fit]
75
+ tuner[Tuner]
76
+ loadStep[load model and tokenizer]
77
+ applyStep[strategy.apply]
78
+ trainStep[TRL trainer]
79
+ metricsStep[MetricsTracker]
80
+ end
81
+
82
+ subgraph outputs [Outputs]
83
+ checkpoint[adapter or checkpoint]
84
+ metricsFile[metrics.json]
85
+ probeRate[probe pass rate]
86
+ end
87
+
88
+ modelId --> tuner
89
+ dataJsonl --> tuner
90
+ strategyNode --> tuner
91
+ objectiveNode --> tuner
92
+ tuner --> loadStep --> applyStep --> trainStep --> metricsStep
93
+ trainStep --> checkpoint
94
+ metricsStep --> metricsFile
95
+ checkpoint --> probeRate
96
+ ```
97
+
98
+ | Axis | Responsibility | Phase 1 |
99
+ | ------------- | --------------------------------- | ----------------------------------------------- |
100
+ | **Strategy** | How weights change (PEFT vs full) | `LoRAStrategy`, `QLoRAStrategy`, `FullStrategy` |
101
+ | **Objective** | What is optimized / data contract | `SFTObjective` (DPO stubbed) |
102
+ | **Data** | Examples β†’ chat `messages` | `load_sft_jsonl` |
103
+ | **Metrics** | Comparable run stats | `MetricsTracker` |
104
+ | **Probe** | Did the model learn *your* facts? | `slick-tune probe` |
105
+
106
+ ## πŸ“Œ Quick Start
107
+
108
+ ```python
109
+ from slicktune import LoRAStrategy, SFTObjective, Tuner
110
+
111
+ Tuner(
112
+ model_id="HuggingFaceTB/SmolLM2-135M-Instruct",
113
+ strategy=LoRAStrategy(r=8),
114
+ objective=SFTObjective(),
115
+ output_dir="outputs/sft_lora",
116
+ ).fit("examples/data/about_amir.jsonl")
117
+ ```
118
+
119
+ ### πŸ‘€ Personal β€œabout me” loop (recommended)
120
+
121
+ 1. Edit `examples/data/about_amir.jsonl` with facts about you (or keep the SlickML starter facts) ✍️.
122
+ 2. Edit `examples/data/about_amir.probes.jsonl` with questions and a `must_contain` substring that should appear after training 🎯.
123
+ 3. Train a strategy on a **tiny** instruct model πŸ§ͺ.
124
+ 4. Probe the checkpoint β€” pass rate shows whether fine-tuning stuck βœ….
125
+
126
+ ```text
127
+ before FT β†’ model guesses / hallucinates about you
128
+ after FT β†’ probe answers contain your facts
129
+ ```
130
+
131
+ ## πŸ›  Installation
132
+
133
+ Install [Python >=3.10,<3.13](https://www.python.org) and [*uv*](https://docs.astral.sh/uv/), then simply run πŸƒβ€β™€οΈ:
134
+
135
+ ```bash
136
+ uv sync
137
+ ```
138
+
139
+ QLoRA (CUDA + bitsandbytes only) πŸ”₯:
140
+
141
+ ```bash
142
+ uv sync --extra qlora
143
+ ```
144
+
145
+ Task runner is [Poe the Poet](https://poethepoet.natn.io/installation.html) (same idea as [slick-ml](https://github.com/slickml/slick-ml), with `uv` instead of Poetry). Install the CLI once πŸƒβ€β™€οΈ:
146
+
147
+ ```bash
148
+ uv tool install poethepoet
149
+ poe greet
150
+ ```
151
+
152
+ Developer workflow (`format` / `check` / `test`) lives in [CONTRIBUTING.md](CONTRIBUTING.md) πŸ§‘β€πŸ’»πŸ€.
153
+
154
+ ## πŸš‚ Train each strategy
155
+
156
+ Default demo model: `HuggingFaceTB/SmolLM2-135M-Instruct` (small enough for laptop smoke tests) πŸ’».
157
+
158
+ ### 🟒 LoRA + SFT (default β€” works on Mac MPS / CPU / CUDA)
159
+
160
+ ```bash
161
+ uv run slick-tune train \
162
+ --strategy lora \
163
+ --data examples/data/about_amir.jsonl \
164
+ --output outputs/sft_lora \
165
+ --epochs 20
166
+
167
+ uv run slick-tune probe \
168
+ --model-dir outputs/sft_lora \
169
+ --probes examples/data/about_amir.probes.jsonl
170
+ ```
171
+
172
+ Or: `poe train-lora` / `poe probe-lora` / `uv run python examples/run_sft_lora.py`
173
+
174
+ ### πŸ”΅ QLoRA + SFT (CUDA required)
175
+
176
+ ```bash
177
+ uv sync --extra qlora
178
+ uv run python examples/run_sft_qlora.py
179
+ ```
180
+
181
+ On Apple Silicon, use LoRA instead β€” bitsandbytes 4-bit needs CUDA 🍎.
182
+
183
+ ### 🟠 Full fine-tuning + SFT
184
+
185
+ ```bash
186
+ uv run python examples/run_sft_full.py
187
+ ```
188
+
189
+ Heavier on memory; prefer LoRA for iteration πŸ’Ύ.
190
+
191
+ ## πŸ“¦ Data formats
192
+
193
+ **SFT JSONL** (any of these per line) πŸ“:
194
+
195
+ ```json
196
+ {"messages":[{"role":"user","content":"..."},{"role":"assistant","content":"..."}]}
197
+ {"prompt":"...","response":"..."}
198
+ {"instruction":"...","input":"...","output":"..."}
199
+ ```
200
+
201
+ **Probe JSONL** πŸ•΅οΈ:
202
+
203
+ ```json
204
+ {"prompt":"Who is Amirhessam Tahmassebi?","must_contain":"SlickML"}
205
+ ```
206
+
207
+ ## πŸ—Ί Roadmap
208
+
209
+ | Phase | Scope |
210
+ | --------- | ------------------------------------------------------------- |
211
+ | 0–1 (now) | Skeleton, SFT + LoRA/QLoRA/full, metrics, personal probe loop |
212
+ | 2 | DoRA / AdaLoRA, richer eval |
213
+ | 3 | DPO / ORPO / KTO |
214
+ | 4 | GRPO / verifiable RL |
215
+ | 5 | Merge (TIES/DARE), multi-adapter |
216
+ | 6 | Optional PPO / multimodal |
217
+
218
+ ## πŸ§‘β€πŸ’»πŸ€ Contributing to slick-tune
219
+
220
+ You can find the details of the development process in our [Contributing](CONTRIBUTING.md) guidelines.
221
+ We strongly believe that reading and following these guidelines will help us make the contribution process easy and effective for everyone involved πŸš€πŸŒ™.
222
+
223
+ Conventions in short: **`@dataclass` classes**, **numpydoc** docstrings, full type hints via **ruff** (`ANN`) + **mypy**, **assertpy** in tests (see `.cursor/rules/`).
224
+
225
+ ## ❓ πŸ†˜ πŸ“² Need Help?
226
+
227
+ Please join our [Slack Channel](https://www.slickml.com/slack-invite) to interact directly with the core team and our small community. This is a good place to discuss your questions and ideas or in general ask for help πŸ‘¨β€πŸ‘©β€πŸ‘§ πŸ‘« πŸ‘¨β€πŸ‘©β€πŸ‘¦.
@@ -0,0 +1,188 @@
1
+ <p align="center">
2
+ <img src="assets/design/logo.png" alt="slick-tune logo" width="420"/>
3
+ </p>
4
+
5
+ # SlickTune 🧩: Composable LLM fine-tuning by [SlickML](https://github.com/slickml)
6
+
7
+
8
+ Fine-tuning is an orthogonal stack β€” swap any axis without rewriting the others:
9
+
10
+ ```text
11
+ model Γ— strategy Γ— objective Γ— data Γ— metrics
12
+ ```
13
+
14
+ ## 🧠 Philosophy
15
+
16
+ **slick-tune** is a small, composable toolkit for teaching LLMs new facts and behaviors with
17
+ [Transformers](https://huggingface.co/docs/transformers) + [PEFT](https://huggingface.co/docs/peft) + [TRL](https://huggingface.co/docs/trl).
18
+ LoRA / QLoRA are PEFT adapters; full FT updates every weight. The goal is the same SlickML spirit:
19
+ prototype fast 🏎, keep axes orthogonal, and measure whether the model actually learned *your* facts πŸ”Ž.
20
+
21
+ ## 🧩 Abstractions
22
+
23
+ ```mermaid
24
+ flowchart TB
25
+ subgraph inputs [Inputs]
26
+ modelId[model_id]
27
+ dataJsonl[data JSONL]
28
+ end
29
+
30
+ subgraph axes [Composable axes]
31
+ strategyNode["Strategy: LoRA / QLoRA / Full"]
32
+ objectiveNode["Objective: SFT then DPO / GRPO"]
33
+ end
34
+
35
+ subgraph core [Tuner fit]
36
+ tuner[Tuner]
37
+ loadStep[load model and tokenizer]
38
+ applyStep[strategy.apply]
39
+ trainStep[TRL trainer]
40
+ metricsStep[MetricsTracker]
41
+ end
42
+
43
+ subgraph outputs [Outputs]
44
+ checkpoint[adapter or checkpoint]
45
+ metricsFile[metrics.json]
46
+ probeRate[probe pass rate]
47
+ end
48
+
49
+ modelId --> tuner
50
+ dataJsonl --> tuner
51
+ strategyNode --> tuner
52
+ objectiveNode --> tuner
53
+ tuner --> loadStep --> applyStep --> trainStep --> metricsStep
54
+ trainStep --> checkpoint
55
+ metricsStep --> metricsFile
56
+ checkpoint --> probeRate
57
+ ```
58
+
59
+ | Axis | Responsibility | Phase 1 |
60
+ | ------------- | --------------------------------- | ----------------------------------------------- |
61
+ | **Strategy** | How weights change (PEFT vs full) | `LoRAStrategy`, `QLoRAStrategy`, `FullStrategy` |
62
+ | **Objective** | What is optimized / data contract | `SFTObjective` (DPO stubbed) |
63
+ | **Data** | Examples β†’ chat `messages` | `load_sft_jsonl` |
64
+ | **Metrics** | Comparable run stats | `MetricsTracker` |
65
+ | **Probe** | Did the model learn *your* facts? | `slick-tune probe` |
66
+
67
+ ## πŸ“Œ Quick Start
68
+
69
+ ```python
70
+ from slicktune import LoRAStrategy, SFTObjective, Tuner
71
+
72
+ Tuner(
73
+ model_id="HuggingFaceTB/SmolLM2-135M-Instruct",
74
+ strategy=LoRAStrategy(r=8),
75
+ objective=SFTObjective(),
76
+ output_dir="outputs/sft_lora",
77
+ ).fit("examples/data/about_amir.jsonl")
78
+ ```
79
+
80
+ ### πŸ‘€ Personal β€œabout me” loop (recommended)
81
+
82
+ 1. Edit `examples/data/about_amir.jsonl` with facts about you (or keep the SlickML starter facts) ✍️.
83
+ 2. Edit `examples/data/about_amir.probes.jsonl` with questions and a `must_contain` substring that should appear after training 🎯.
84
+ 3. Train a strategy on a **tiny** instruct model πŸ§ͺ.
85
+ 4. Probe the checkpoint β€” pass rate shows whether fine-tuning stuck βœ….
86
+
87
+ ```text
88
+ before FT β†’ model guesses / hallucinates about you
89
+ after FT β†’ probe answers contain your facts
90
+ ```
91
+
92
+ ## πŸ›  Installation
93
+
94
+ Install [Python >=3.10,<3.13](https://www.python.org) and [*uv*](https://docs.astral.sh/uv/), then simply run πŸƒβ€β™€οΈ:
95
+
96
+ ```bash
97
+ uv sync
98
+ ```
99
+
100
+ QLoRA (CUDA + bitsandbytes only) πŸ”₯:
101
+
102
+ ```bash
103
+ uv sync --extra qlora
104
+ ```
105
+
106
+ Task runner is [Poe the Poet](https://poethepoet.natn.io/installation.html) (same idea as [slick-ml](https://github.com/slickml/slick-ml), with `uv` instead of Poetry). Install the CLI once πŸƒβ€β™€οΈ:
107
+
108
+ ```bash
109
+ uv tool install poethepoet
110
+ poe greet
111
+ ```
112
+
113
+ Developer workflow (`format` / `check` / `test`) lives in [CONTRIBUTING.md](CONTRIBUTING.md) πŸ§‘β€πŸ’»πŸ€.
114
+
115
+ ## πŸš‚ Train each strategy
116
+
117
+ Default demo model: `HuggingFaceTB/SmolLM2-135M-Instruct` (small enough for laptop smoke tests) πŸ’».
118
+
119
+ ### 🟒 LoRA + SFT (default β€” works on Mac MPS / CPU / CUDA)
120
+
121
+ ```bash
122
+ uv run slick-tune train \
123
+ --strategy lora \
124
+ --data examples/data/about_amir.jsonl \
125
+ --output outputs/sft_lora \
126
+ --epochs 20
127
+
128
+ uv run slick-tune probe \
129
+ --model-dir outputs/sft_lora \
130
+ --probes examples/data/about_amir.probes.jsonl
131
+ ```
132
+
133
+ Or: `poe train-lora` / `poe probe-lora` / `uv run python examples/run_sft_lora.py`
134
+
135
+ ### πŸ”΅ QLoRA + SFT (CUDA required)
136
+
137
+ ```bash
138
+ uv sync --extra qlora
139
+ uv run python examples/run_sft_qlora.py
140
+ ```
141
+
142
+ On Apple Silicon, use LoRA instead β€” bitsandbytes 4-bit needs CUDA 🍎.
143
+
144
+ ### 🟠 Full fine-tuning + SFT
145
+
146
+ ```bash
147
+ uv run python examples/run_sft_full.py
148
+ ```
149
+
150
+ Heavier on memory; prefer LoRA for iteration πŸ’Ύ.
151
+
152
+ ## πŸ“¦ Data formats
153
+
154
+ **SFT JSONL** (any of these per line) πŸ“:
155
+
156
+ ```json
157
+ {"messages":[{"role":"user","content":"..."},{"role":"assistant","content":"..."}]}
158
+ {"prompt":"...","response":"..."}
159
+ {"instruction":"...","input":"...","output":"..."}
160
+ ```
161
+
162
+ **Probe JSONL** πŸ•΅οΈ:
163
+
164
+ ```json
165
+ {"prompt":"Who is Amirhessam Tahmassebi?","must_contain":"SlickML"}
166
+ ```
167
+
168
+ ## πŸ—Ί Roadmap
169
+
170
+ | Phase | Scope |
171
+ | --------- | ------------------------------------------------------------- |
172
+ | 0–1 (now) | Skeleton, SFT + LoRA/QLoRA/full, metrics, personal probe loop |
173
+ | 2 | DoRA / AdaLoRA, richer eval |
174
+ | 3 | DPO / ORPO / KTO |
175
+ | 4 | GRPO / verifiable RL |
176
+ | 5 | Merge (TIES/DARE), multi-adapter |
177
+ | 6 | Optional PPO / multimodal |
178
+
179
+ ## πŸ§‘β€πŸ’»πŸ€ Contributing to slick-tune
180
+
181
+ You can find the details of the development process in our [Contributing](CONTRIBUTING.md) guidelines.
182
+ We strongly believe that reading and following these guidelines will help us make the contribution process easy and effective for everyone involved πŸš€πŸŒ™.
183
+
184
+ Conventions in short: **`@dataclass` classes**, **numpydoc** docstrings, full type hints via **ruff** (`ANN`) + **mypy**, **assertpy** in tests (see `.cursor/rules/`).
185
+
186
+ ## ❓ πŸ†˜ πŸ“² Need Help?
187
+
188
+ Please join our [Slack Channel](https://www.slickml.com/slack-invite) to interact directly with the core team and our small community. This is a good place to discuss your questions and ideas or in general ask for help πŸ‘¨β€πŸ‘©β€πŸ‘§ πŸ‘« πŸ‘¨β€πŸ‘©β€πŸ‘¦.