telos-ml 1.0.0__py3-none-any.whl

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.
Files changed (86) hide show
  1. telos/__init__.py +74 -0
  2. telos/__main__.py +9 -0
  3. telos/afm/__init__.py +67 -0
  4. telos/afm/_swift/afm_bridge.swift +136 -0
  5. telos/afm/availability.py +195 -0
  6. telos/afm/bridge.py +246 -0
  7. telos/afm/cli.py +96 -0
  8. telos/assets/__init__.py +1 -0
  9. telos/assets/tokenizer_0.json +20145 -0
  10. telos/bench/__init__.py +15 -0
  11. telos/bench/__main__.py +4 -0
  12. telos/bench/runner.py +81 -0
  13. telos/cli.py +73 -0
  14. telos/configs/__init__.py +9 -0
  15. telos/configs/builder.py +460 -0
  16. telos/configs/solver.py +142 -0
  17. telos/data/__init__.py +21 -0
  18. telos/data/tokenizer.py +91 -0
  19. telos/dataprep/__init__.py +16 -0
  20. telos/dataprep/__main__.py +4 -0
  21. telos/dataprep/prepare.py +348 -0
  22. telos/diffusion/__init__.py +90 -0
  23. telos/diffusion/ar.py +88 -0
  24. telos/diffusion/corosred.py +628 -0
  25. telos/diffusion/corosred_unified.py +363 -0
  26. telos/diffusion/mdlm.py +164 -0
  27. telos/diffusion/refiner.py +148 -0
  28. telos/diffusion/region.py +236 -0
  29. telos/diffusion/sampler.py +237 -0
  30. telos/diffusion/undlm.py +119 -0
  31. telos/eval/__init__.py +69 -0
  32. telos/eval/__main__.py +4 -0
  33. telos/eval/adapters/__init__.py +20 -0
  34. telos/eval/adapters/base.py +78 -0
  35. telos/eval/adapters/gemini_api.py +129 -0
  36. telos/eval/adapters/huggingface.py +99 -0
  37. telos/eval/adapters/mlx_lm.py +51 -0
  38. telos/eval/adapters/openai_api.py +179 -0
  39. telos/eval/adapters/registry.py +132 -0
  40. telos/eval/adapters/swift_afm.py +84 -0
  41. telos/eval/adapters/telos_native.py +82 -0
  42. telos/eval/anticheat.py +217 -0
  43. telos/eval/contamination.py +129 -0
  44. telos/eval/cyber_eval.py +120 -0
  45. telos/eval/executor.py +220 -0
  46. telos/eval/linguistic/__init__.py +19 -0
  47. telos/eval/linguistic/evaluator.py +442 -0
  48. telos/eval/linguistic/probes_en.py +1162 -0
  49. telos/eval/metrics.py +208 -0
  50. telos/eval/polyglot_eval.py +207 -0
  51. telos/eval/probes.py +160 -0
  52. telos/eval/reasoning_eval.py +167 -0
  53. telos/eval/runner.py +1562 -0
  54. telos/eval/stats.py +46 -0
  55. telos/eval/syntax.py +114 -0
  56. telos/eval/tooluse/__init__.py +21 -0
  57. telos/eval/tooluse/evaluator.py +326 -0
  58. telos/eval/tooluse/suite.py +341 -0
  59. telos/models/__init__.py +25 -0
  60. telos/models/components.py +143 -0
  61. telos/models/config.py +26 -0
  62. telos/models/mlx_components.py +106 -0
  63. telos/models/mlx_transformer.py +95 -0
  64. telos/models/param_counter.py +65 -0
  65. telos/models/transformer.py +107 -0
  66. telos/models/upscale.py +45 -0
  67. telos/testing/__init__.py +11 -0
  68. telos/testing/suite.py +329 -0
  69. telos/train/__init__.py +15 -0
  70. telos/train/__main__.py +4 -0
  71. telos/train/cli.py +514 -0
  72. telos/training/__init__.py +63 -0
  73. telos/training/core.py +233 -0
  74. telos/training/dataloader.py +68 -0
  75. telos/training/hardware.py +102 -0
  76. telos/training/lr_schedule.py +46 -0
  77. telos/training/monitor.py +188 -0
  78. telos/training/schedule.py +296 -0
  79. telos/training/trainer_mlx.py +547 -0
  80. telos/training/trainer_pytorch.py +1046 -0
  81. telos/training/xla_utils.py +180 -0
  82. telos_ml-1.0.0.dist-info/METADATA +234 -0
  83. telos_ml-1.0.0.dist-info/RECORD +86 -0
  84. telos_ml-1.0.0.dist-info/WHEEL +4 -0
  85. telos_ml-1.0.0.dist-info/entry_points.txt +2 -0
  86. telos_ml-1.0.0.dist-info/licenses/LICENSE +190 -0
telos/__init__.py ADDED
@@ -0,0 +1,74 @@
1
+ """
2
+ télos (τέλος): Discrete Diffusion & Autoregressive Language Modeling Framework.
3
+ """
4
+
5
+ from importlib.metadata import version as _pkg_version, PackageNotFoundError
6
+
7
+ try:
8
+ __version__ = _pkg_version("telos-ml")
9
+ except PackageNotFoundError:
10
+ try:
11
+ __version__ = _pkg_version("telos")
12
+ except PackageNotFoundError:
13
+ __version__ = "1.0.0"
14
+
15
+ from . import dataprep
16
+ from . import train
17
+ from . import eval
18
+ from . import bench
19
+ from .training.hardware import HardwareProfile
20
+
21
+ from .models.config import TelosConfig
22
+
23
+ # Primary callable aliases
24
+ prepare_dataset = dataprep.prepare_dataset
25
+ run_train = train.train
26
+ evaluate = eval.evaluate
27
+ benchmark = bench.benchmark
28
+
29
+ _TORCH_IMPORTS = {
30
+ "TelosTransformer": ".models.transformer",
31
+ "UnifiedPyTorchTrainer": ".training.trainer_pytorch",
32
+ }
33
+
34
+ def __getattr__(name: str):
35
+ if name == "afm":
36
+ import importlib
37
+ return importlib.import_module(".afm", __package__)
38
+ if name == "MLXTelosTransformer":
39
+ from .models import MLXTelosTransformer
40
+ return MLXTelosTransformer
41
+ if name == "UnifiedMLXTrainer":
42
+ from .training import UnifiedMLXTrainer
43
+ return UnifiedMLXTrainer
44
+ if name in _TORCH_IMPORTS:
45
+ try:
46
+ import importlib
47
+ mod = importlib.import_module(_TORCH_IMPORTS[name], __package__)
48
+ return getattr(mod, name)
49
+ except ImportError as err:
50
+ raise ImportError(
51
+ f"{name} requires 'torch', which is not available in this environment. "
52
+ "Install it via `pip install torch`."
53
+ ) from err
54
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
55
+
56
+ __all__ = [
57
+ "__version__",
58
+ "dataprep",
59
+ "train",
60
+ "run_train",
61
+ "eval",
62
+ "bench",
63
+ "prepare_dataset",
64
+ "evaluate",
65
+ "benchmark",
66
+ "afm",
67
+ "TelosTransformer",
68
+ "TelosConfig",
69
+ "MLXTelosTransformer",
70
+ "UnifiedMLXTrainer",
71
+ "UnifiedPyTorchTrainer",
72
+ "HardwareProfile",
73
+ ]
74
+
telos/__main__.py ADDED
@@ -0,0 +1,9 @@
1
+ """
2
+ telos.__main__
3
+ Entry point enabling `python -m telos`.
4
+ """
5
+
6
+ from .cli import main
7
+
8
+ if __name__ == "__main__":
9
+ main()
telos/afm/__init__.py ADDED
@@ -0,0 +1,67 @@
1
+ """
2
+ telos.afm
3
+ Python access to Apple's on-device Foundation Models.
4
+
5
+ Usage:
6
+ >>> import telos.afm
7
+ >>> telos.afm.probe().describe()
8
+ >>> telos.afm.generate("Write a haiku about gradients.")
9
+
10
+ Requires macOS 26+, an Apple Intelligence-eligible Apple Silicon Mac with it
11
+ enabled, and the Xcode Command Line Tools. The Swift bridge is built on first
12
+ use into ~/.cache/telos (override with TELOS_CACHE_DIR).
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ from typing import Optional, Sequence
18
+
19
+ from .availability import (
20
+ AFMAvailability,
21
+ AFMUnavailableError,
22
+ FALLBACK_CHIP_FAMILY,
23
+ MIN_MACOS_MAJOR,
24
+ MODEL_CORE,
25
+ MODEL_CORE_ADVANCED,
26
+ probe,
27
+ require,
28
+ )
29
+ from .bridge import AFMBridge, cache_root, ensure_bridge_binary
30
+
31
+ __all__ = [
32
+ "AFMAvailability",
33
+ "AFMBridge",
34
+ "AFMUnavailableError",
35
+ "FALLBACK_CHIP_FAMILY",
36
+ "MIN_MACOS_MAJOR",
37
+ "MODEL_CORE",
38
+ "MODEL_CORE_ADVANCED",
39
+ "cache_root",
40
+ "ensure_bridge_binary",
41
+ "generate",
42
+ "probe",
43
+ "require",
44
+ ]
45
+
46
+
47
+ def generate(
48
+ prompt: str,
49
+ *,
50
+ max_new_tokens: int = 256,
51
+ temperature: float = 0.0,
52
+ stop: Optional[Sequence[str]] = None,
53
+ instructions: Optional[str] = None,
54
+ ) -> str:
55
+ """Generates one completion on the on-device model.
56
+
57
+ Opens a bridge, generates, and closes it. Hold an AFMBridge open for
58
+ repeated calls so the process and model stay warm.
59
+ """
60
+ with AFMBridge() as bridge:
61
+ return bridge.generate(
62
+ prompt,
63
+ max_new_tokens=max_new_tokens,
64
+ temperature=temperature,
65
+ stop=stop,
66
+ instructions=instructions,
67
+ )
@@ -0,0 +1,136 @@
1
+ import Foundation
2
+ import FoundationModels
3
+
4
+ struct GenerationRequest: Codable {
5
+ let id: Int?
6
+ let prompt: String
7
+ let instructions: String?
8
+ let maxTokens: Int?
9
+ let temperature: Double?
10
+ let stopTokens: [String]?
11
+ }
12
+
13
+ struct GenerationResponse: Codable {
14
+ let id: Int?
15
+ let content: String
16
+ let error: String?
17
+ }
18
+
19
+ /// One-shot availability report, emitted for `afm_bridge --status`.
20
+ ///
21
+ /// `FoundationModels` exposes no public selector for a specific on-device
22
+ /// model, only `SystemLanguageModel.default`. The `check` field therefore
23
+ /// reports *why* the default model is or is not usable, and the Python side
24
+ /// maps that onto the Core / Core Advanced preference.
25
+ struct StatusResponse: Codable {
26
+ let available: Bool
27
+ /// One of: "available", "device_not_eligible",
28
+ /// "apple_intelligence_not_enabled", "model_not_ready", "unknown".
29
+ let check: String
30
+ let detail: String?
31
+ }
32
+
33
+ func describeAvailability(_ model: SystemLanguageModel) -> StatusResponse {
34
+ switch model.availability {
35
+ case .available:
36
+ return StatusResponse(available: true, check: "available", detail: nil)
37
+ case .unavailable(let reason):
38
+ switch reason {
39
+ case .deviceNotEligible:
40
+ return StatusResponse(
41
+ available: false,
42
+ check: "device_not_eligible",
43
+ detail: "This device is not eligible for Apple Intelligence."
44
+ )
45
+ case .appleIntelligenceNotEnabled:
46
+ return StatusResponse(
47
+ available: false,
48
+ check: "apple_intelligence_not_enabled",
49
+ detail: "Apple Intelligence is not enabled in System Settings."
50
+ )
51
+ case .modelNotReady:
52
+ return StatusResponse(
53
+ available: false,
54
+ check: "model_not_ready",
55
+ detail: "The on-device model is still downloading or preparing."
56
+ )
57
+ @unknown default:
58
+ return StatusResponse(available: false, check: "unknown", detail: "\(reason)")
59
+ }
60
+ @unknown default:
61
+ return StatusResponse(available: false, check: "unknown", detail: nil)
62
+ }
63
+ }
64
+
65
+ func emitJSON<T: Encodable>(_ value: T) {
66
+ if let data = try? JSONEncoder().encode(value),
67
+ let str = String(data: data, encoding: .utf8) {
68
+ print(str)
69
+ fflush(stdout)
70
+ }
71
+ }
72
+
73
+ @main
74
+ struct AFMBridge {
75
+ static func main() async {
76
+ let model = SystemLanguageModel.default
77
+
78
+ // One-shot status probe: `afm_bridge --status`. Exits immediately so
79
+ // the Python side can report availability without opening a session.
80
+ if CommandLine.arguments.contains("--status") {
81
+ emitJSON(describeAvailability(model))
82
+ return
83
+ }
84
+
85
+ guard model.isAvailable else {
86
+ let resp = GenerationResponse(id: nil, content: "", error: "SystemLanguageModel is not available on this system.")
87
+ emitJSON(resp)
88
+ return
89
+ }
90
+
91
+ let stdin = FileHandle.standardInput
92
+ while let lineData = try? stdin.readLine() {
93
+ guard !lineData.isEmpty else { continue }
94
+ guard let req = try? JSONDecoder().decode(GenerationRequest.self, from: lineData) else {
95
+ continue
96
+ }
97
+
98
+ let instructions = req.instructions ?? "You are an expert programming and reasoning assistant. Provide direct, concise, and accurate output without conversational filler."
99
+ let session = LanguageModelSession(model: model, instructions: instructions)
100
+ let options = GenerationOptions(
101
+ temperature: req.temperature ?? 0.0,
102
+ maximumResponseTokens: req.maxTokens ?? 256
103
+ )
104
+
105
+ do {
106
+ let response = try await session.respond(to: req.prompt, options: options)
107
+ var text = response.content
108
+ if let stopTokens = req.stopTokens {
109
+ for stop in stopTokens {
110
+ if let range = text.range(of: stop) {
111
+ text = String(text[..<range.lowerBound])
112
+ }
113
+ }
114
+ }
115
+ emitJSON(GenerationResponse(id: req.id, content: text, error: nil))
116
+ } catch {
117
+ emitJSON(GenerationResponse(id: req.id, content: "", error: "\(error)"))
118
+ }
119
+ }
120
+ }
121
+ }
122
+
123
+ extension FileHandle {
124
+ func readLine() throws -> Data? {
125
+ var buffer = Data()
126
+ while true {
127
+ guard let byteData = try self.read(upToCount: 1), !byteData.isEmpty else {
128
+ return buffer.isEmpty ? nil : buffer
129
+ }
130
+ if byteData[0] == 10 { // newline \n
131
+ return buffer
132
+ }
133
+ buffer.append(byteData)
134
+ }
135
+ }
136
+ }
@@ -0,0 +1,195 @@
1
+ """
2
+ AFM Availability
3
+ Detects whether Apple's on-device Foundation Models are usable on this machine.
4
+
5
+ FoundationModels exposes only `SystemLanguageModel.default`, so this detects
6
+ eligibility and names what is called rather than switching models at runtime.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import platform
12
+ import re
13
+ import shutil
14
+ import subprocess
15
+ from dataclasses import dataclass
16
+ from typing import Optional
17
+
18
+ from .bridge import AFMUnavailableError, query_status
19
+
20
+ __all__ = [
21
+ "AFMAvailability",
22
+ "AFMUnavailableError",
23
+ "MIN_MACOS_MAJOR",
24
+ "FALLBACK_CHIP_FAMILY",
25
+ "probe",
26
+ "require",
27
+ ]
28
+
29
+ MIN_MACOS_MAJOR = 26
30
+ FALLBACK_CHIP_FAMILY = "M3"
31
+
32
+ MODEL_CORE_ADVANCED = "afm-3-core-advanced"
33
+ MODEL_CORE = "afm-3-core"
34
+
35
+
36
+ @dataclass(frozen=True)
37
+ class AFMAvailability:
38
+ """Outcome of an on-device Foundation Models probe."""
39
+
40
+ available: bool
41
+ #: Name of the model being called, or None when unavailable.
42
+ model: Optional[str]
43
+ #: Smaller model offered as fallback on M3+, or None on older silicon.
44
+ fallback_model: Optional[str]
45
+ #: "ok" when available, otherwise why not.
46
+ reason: str
47
+ macos_version: Optional[tuple[int, ...]]
48
+ chip_family: Optional[str]
49
+ framework_check: Optional[str]
50
+ xcode_clt: bool
51
+ swiftc: bool
52
+
53
+ def describe(self) -> str:
54
+ """One-line human summary."""
55
+ if self.available:
56
+ line = f"{self.model} available (Apple on-device Foundation Models)."
57
+ if self.fallback_model:
58
+ line += f" Fallback on this chip: {self.fallback_model}."
59
+ return line
60
+ return f"Apple on-device Foundation Models unavailable: {self.reason}"
61
+
62
+
63
+ def _parse_macos_major(ver: str) -> Optional[tuple[int, ...]]:
64
+ parts = []
65
+ for chunk in ver.split("."):
66
+ if not chunk.isdigit():
67
+ break
68
+ parts.append(int(chunk))
69
+ return tuple(parts) if parts else None
70
+
71
+
72
+ def _chip_family() -> Optional[str]:
73
+ # sysctl can be blocked by a sandbox; unknown is fine, runtime check decides.
74
+ try:
75
+ res = subprocess.run(
76
+ ["sysctl", "-n", "machdep.cpu.brand_string"],
77
+ capture_output=True,
78
+ text=True,
79
+ timeout=5,
80
+ )
81
+ except (OSError, subprocess.SubprocessError):
82
+ return None
83
+ if res.returncode != 0:
84
+ return None
85
+ match = re.search(r"\bApple\s+(M\d+)", res.stdout)
86
+ return match.group(1) if match else None
87
+
88
+
89
+ def _chip_at_least(family: Optional[str], minimum: str) -> bool:
90
+ if family is None:
91
+ return False
92
+ m = re.fullmatch(r"M(\d+)", family)
93
+ n = re.fullmatch(r"M(\d+)", minimum)
94
+ if not m or not n:
95
+ return False
96
+ return int(m.group(1)) >= int(n.group(1))
97
+
98
+
99
+ def _has_xcode_clt() -> bool:
100
+ try:
101
+ res = subprocess.run(["xcode-select", "-p"], capture_output=True, text=True, timeout=5)
102
+ except (OSError, subprocess.SubprocessError):
103
+ return False
104
+ return res.returncode == 0
105
+
106
+
107
+ def probe(*, runtime: bool = True) -> AFMAvailability:
108
+ """Detects whether the on-device models are usable. Never raises for an
109
+ unsupported machine; inspect `available` and `reason` instead."""
110
+ if platform.system() != "Darwin":
111
+ return AFMAvailability(
112
+ available=False,
113
+ model=None,
114
+ fallback_model=None,
115
+ reason=f"Apple Foundation Models are macOS-only (this is {platform.system()}).",
116
+ macos_version=None,
117
+ chip_family=None,
118
+ framework_check=None,
119
+ xcode_clt=False,
120
+ swiftc=False,
121
+ )
122
+
123
+ macos_ver = _parse_macos_major(platform.mac_ver()[0])
124
+ chip = _chip_family()
125
+ has_clt = _has_xcode_clt()
126
+ has_swiftc = shutil.which("swiftc") is not None
127
+
128
+ def unavailable(reason: str, framework_check: Optional[str] = None) -> AFMAvailability:
129
+ return AFMAvailability(
130
+ available=False,
131
+ model=None,
132
+ fallback_model=None,
133
+ reason=reason,
134
+ macos_version=macos_ver,
135
+ chip_family=chip,
136
+ framework_check=framework_check,
137
+ xcode_clt=has_clt,
138
+ swiftc=has_swiftc,
139
+ )
140
+
141
+ if platform.machine() != "arm64":
142
+ return unavailable(f"Apple Foundation Models require Apple Silicon (this is {platform.machine()}).")
143
+ if macos_ver is None:
144
+ return unavailable("Could not determine the macOS version.")
145
+ if macos_ver[0] < MIN_MACOS_MAJOR:
146
+ return unavailable(
147
+ f"Apple Foundation Models require macOS {MIN_MACOS_MAJOR} or later "
148
+ f"(this is {'.'.join(map(str, macos_ver))})."
149
+ )
150
+
151
+ fallback = MODEL_CORE if _chip_at_least(chip, FALLBACK_CHIP_FAMILY) else None
152
+
153
+ if not runtime:
154
+ # Platform can host the framework; Apple Intelligence state is runtime-only.
155
+ return AFMAvailability(
156
+ available=True,
157
+ model=MODEL_CORE_ADVANCED,
158
+ fallback_model=fallback,
159
+ reason="ok",
160
+ macos_version=macos_ver,
161
+ chip_family=chip,
162
+ framework_check=None,
163
+ xcode_clt=has_clt,
164
+ swiftc=has_swiftc,
165
+ )
166
+
167
+ try:
168
+ status = query_status()
169
+ except AFMUnavailableError as exc:
170
+ return unavailable(exc.reason)
171
+
172
+ check = str(status.get("check", "unknown"))
173
+ if not status.get("available"):
174
+ detail = status.get("detail") or None
175
+ return unavailable(detail or f"The on-device model is unavailable ({check}).", check)
176
+
177
+ return AFMAvailability(
178
+ available=True,
179
+ model=MODEL_CORE_ADVANCED,
180
+ fallback_model=fallback,
181
+ reason="ok",
182
+ macos_version=macos_ver,
183
+ chip_family=chip,
184
+ framework_check=check,
185
+ xcode_clt=has_clt,
186
+ swiftc=has_swiftc,
187
+ )
188
+
189
+
190
+ def require(*, runtime: bool = True) -> AFMAvailability:
191
+ """Like probe(), but raises when the models are unavailable."""
192
+ avail = probe(runtime=runtime)
193
+ if not avail.available:
194
+ raise AFMUnavailableError(avail.reason)
195
+ return avail