Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
Sichere ProgrammierungWhat is Programming And How i can Enjoy it?(24.09.2026 um 11:54 Uhr)
Sichere ProgrammierungYou Don't Need Adobe Commerce Cloud to Survive Black Friday(24.09.2026 um 11:55 Uhr)
Malware / Trojaner / VirenBeyond Lazarus: Organization of DPRK cyber capabilities(24.09.2026 um 11:59 Uhr)
Malware / Trojaner / VirenBeyond Lazarus: Organization of DPRK Cyber Capabilities(24.09.2026 um 11:59 Uhr)
Malware / Trojaner / VirenThe fake worker threat and the rise of human infiltration(24.09.2026 um 11:59 Uhr)
Malware / Trojaner / VirenPolinRider Spreads Through Compromised GitHub Accounts and Packagist(24.09.2026 um 11:59 Uhr)
Malware / Trojaner / VirenWeaselBiscuit Strips BeaverTail and OtterCookie Down to Essentials(24.09.2026 um 11:59 Uhr)
Sichere ProgrammierungWhat is Programming And How i can Enjoy it?(24.09.2026 um 11:54 Uhr)
Sichere ProgrammierungYou Don't Need Adobe Commerce Cloud to Survive Black Friday(24.09.2026 um 11:55 Uhr)
Malware / Trojaner / VirenBeyond Lazarus: Organization of DPRK cyber capabilities(24.09.2026 um 11:59 Uhr)
Malware / Trojaner / VirenBeyond Lazarus: Organization of DPRK Cyber Capabilities(24.09.2026 um 11:59 Uhr)
Malware / Trojaner / VirenThe fake worker threat and the rise of human infiltration(24.09.2026 um 11:59 Uhr)
Malware / Trojaner / VirenPolinRider Spreads Through Compromised GitHub Accounts and Packagist(24.09.2026 um 11:59 Uhr)
Malware / Trojaner / VirenWeaselBiscuit Strips BeaverTail and OtterCookie Down to Essentials(24.09.2026 um 11:59 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

Processing 1M Chess Games in 15 Seconds with Rust

I train self-supervised models on chess game data. My Python pipeline using python-chess took 25 minutes to parse and tokenize 1M games from Lichess PGN dumps. I rewrote it in Rust. It now takes 15 seconds. This post covers the…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!

I train self-supervised models on chess game data. My Python pipeline using python-chess took 25 minutes to parse and tokenize 1M games from Lichess PGN dumps. I rewrote it in Rust. It now takes 15 seconds.



This post covers the architecture, why Rust was the right choice, and what I learned.






The problem



Training a chess move predictor requires converting PGN (Portable Game Notation) files into tokenized sequences — arrays of integer IDs that a neural network can consume. A typical Lichess monthly dump has 5M+ games in a zstd-compressed PGN file.



My Python pipeline had three bottlenecks:





  1. PGN parsing — python-chess parses SAN notation, validates moves on a board, handles edge cases. Correct, but slow. ~15 minutes for 1M games.


  2. Tokenization — converting validated UCI moves to token IDs, tracking piece types and turns. ~10 minutes.


  3. Memory — all games loaded into a Python list of dicts. 1M games = ~4GB RAM.






The Rust rewrite



The tool is called ailed-soulsteal (named after a Castlevania ability — the project has a theme).






Architecture



Three layers, each a clean boundary:




Input Layer → Filter Layer → Output Layer
(PGN parser) (ELO, result) (.somabin binary)






Everything streams — games are parsed, filtered, tokenized, and written one at a time. Memory usage stays constant regardless of input size.






PGN parsing



PGN is a messy format. Tags, comments, variations, NAGs, move numbers, results — all interleaved. I wrote a simple streaming parser that yields one RawGame at a time:




struct PgnIterator<R> {
reader: R,
line_buf: String,
}

impl<R: BufRead> Iterator for PgnIterator<R> {
type Item = RawGame;
fn next(&mut self) -> Option<RawGame> {
// Read tags until blank line, then movetext until next blank line
// Strip comments, NAGs, variations, move numbers
// Return (tags, moves, result)
}
}






No allocations per game beyond the reused line buffer. The RawGame struct holds tags as a HashMap<String, String> and moves as Vec<String>.






Move validation with shakmaty



shakmaty is a pure Rust chess library. It handles SAN parsing, move validation, and piece type lookup — the same things python-chess does, but at native speed.




let san: shakmaty::san::San = san_str.parse().ok()?;
let m = san.to_move(&pos).ok()?;
let uci = uci_string(&m);
let category = role_to_category(m.role());
pos = pos.play(&m).ok()?;






This is where most of the speedup comes from. shakmaty's play() is essentially a few bitboard operations — no Python overhead, no GC pressure.






Binary output format



Instead of writing JSON or CSV, I designed a binary format (.somabin) optimized for ML training:




Header (64 bytes): magic, version, vocab_size, num_games, ...
Index Table: byte offset for each game (enables random access)
Data Section: per game: [seq_len, token_ids, turn_ids, category_ids, outcome]






The index table is the key insight. A PyTorch Dataset.__getitem__(i) can seek directly to game i via mmap without scanning the file. Loading 50K games takes 20ms. Random access runs at 500K games/sec.



The Python reader is 30 lines:




class SomabinDataset:
def __init__(self, path):
self._file = open(path, "rb")
self._mm = mmap.mmap(self._file.fileno(), 0, access=mmap.ACCESS_READ)
self.header = read_header(self._mm)
self._index = read_index(self._mm, self.header)

def __getitem__(self, idx):
offset = int(self._index[idx])
return read_game(self._mm, offset)









Zstd decompression



Lichess distributes PGN files as .pgn.zst. The zstd crate handles decompression transparently:




if path.extension() == Some("zst") {
let decoder = zstd::Decoder::new(file)?;
Ok(Box::new(BufReader::with_capacity(1024 * 1024, decoder)))
} else {
Ok(Box::new(BufReader::with_capacity(1024 * 1024, file)))
}






Auto-detected from the file extension. No separate decompression step needed.






Filtering



Games are filtered by metadata before tokenization — no wasted work:




pub trait GameFilter {
fn accept(&self, game: &RawGame) -> bool;
}

// Chain of filters — all must pass
filters.add(Box::new(EloFilter::new(1000, 1800)));
filters.add(Box::new(MovesFilter::new(Some(4), None)));
filters.add(Box::new(ResultFilter::Decisive));






Filters operate on PGN tags (strings), not board positions. Checking WhiteElo >= "1000" is effectively free compared to move validation.






Benchmarks



Processing Lichess monthly dumps (zstd compressed) on an M1 MacBook:


















































Month Input Games (1000-1800) Time Rate
2016-01 831 MB .zst 2,060,197 45s 46K/s
2016-02 866 MB .zst 2,071,332 46s 45K/s
2016-03 994 MB .zst 2,399,234 54s 45K/s
2016-04 1.0 GB .zst 2,438,621 55s 44K/s
2016-07 1.0 GB .zst 2,598,733 59s 44K/s


11.6M games in 4.3 minutes. The equivalent Python pipeline would take roughly 5 hours.






What I learned



Streaming wins. The biggest architectural decision was making everything an iterator. Games flow through parse → filter → tokenize → write without buffering. Memory usage is constant at ~10MB regardless of input size.



Binary formats beat JSON for ML. My first version wrote JSONL. A 1M-game JSONL file was 2GB and took 30 seconds to load in Python. The .somabin binary for the same data is 550MB and loads in 20ms via mmap.



shakmaty is excellent. Chess move validation is the bottleneck in any PGN pipeline. shakmaty's bitboard implementation made this a non-issue. The crate is well-documented and the API maps cleanly to what you need for tokenization.



Rust's type system caught real bugs. The GameParser and GameTokenizer traits enforce separation between parsing (text → structured data) and tokenization (structured data → integers). When I mixed them up during development, the compiler told me immediately.






Try it






cargo install ailed-soulsteal

# Generate vocabulary
soulsteal vocab --generate -o vocab.json

# Tokenize a Lichess dump
soulsteal tokenize lichess_2016-02.pgn.zst \
-o train.somabin \
--vocab vocab.json \
--elo 1000:1800

# Inspect
soulsteal info train.somabin
soulsteal stats train.somabin






Pre-tokenized datasets are available on Hugging Face.



The tool is designed to support any turn-based game — Go (SGF), Shogi (KIF), etc. Chess is the v1 implementation, but the GameParser and GameTokenizer traits are game-agnostic.



Source: github.com/Ailed-AI/ailed-soulsteal

crates.io: ailed-soulsteal

License: MIT

SOC Incident Playbook: Remote Code Execution (RCE) Defense
title: Detect Exploitation - Processing 1M Chess Games in 15 Seconds with Rust
id: 000c03c7-1af1-4fc5-8ff2-2f2f0b3046bb
status: experimental
description: Automatisch generierte SIEM-Erkennungsregel basierend auf CTI Intelligence
references:
  - https://tsecurity.de/
author: iShareStuff CTI Automated Detection Engine
date: 2026-09-24
logsource:
  category: network_connection
  product: any
detection:
  selection:
      CommandLine|contains:
        - 'exploit'
  condition: selection
falsepositives:
  - Legitime administrative Zugriffe oder Penetrationstests
level: high
tags:
  - attack.initial_access
rule CTI_Threat_Indicator {
    meta:
        author = "iShareStuff CTI Automated Detection Engine"
        date = "2026-09-24"
        description = "YARA Signature for "
    strings:
        $str = "Processing 1M Chess Games in 1" ascii wide
    condition:
        any of them
}
tsecurity.de Cognitive Threat RAG
Fokus-Vektor:

Kognitive Analyse für identifizierte Bedrohung: Erhöhte Bedrohungslage im Bereich Processing 1M Chess Games in 15 Seconds .... Basierend auf 368k Vektor-Korrelationen werden sofortige Isolationsmaßnahmen für betroffene Endpunkte empfohlen.

🛡️ Angriffsfläche & Exposure

Netzwerk/Remote-Zugriff ohne Vorauthentifizierung möglich.

Empfohlene Sofortmaßnahmen
  • 1. Perimeter-Inspektion: Relevante Portfreigaben und exponierte Endpunkte unverzüglich scannen.
  • 2. Patch-Applikation: Hersteller-Hotfix einspielen oder betroffene Daemons in isolierte DMZ-Segmente überführen.
  • 3. Telemetrie & EDR-Alerts: Prozessaufrufe und Child-Processes auf anomale Shell-Spawns überwachen.
🔗 Semantisch verwandte Zero-Days MariaDB 11.7 VEC
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Processing 1M Chess Games in 15 Seconds with Rust

Thematisch verwandte Begriffe: Processing, Chess, Games, Seconds · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-97152 | Nanomsg versions 0.5-beta through 1.x before 1.2.3 has a remotely exploi…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel TTP ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick