Unified Model Pipeline with Decoupled Tool Calling
Les mainteneurs répondent en général sous 1 jour
Personne n'a encore pris cette issue.
Évaluation
- Difficulté
- 5/5
- Temps estimé
- Plus d'une semaine
- Accessibilité débutants
- 20/100
Piste de recherche
Read the Phase 1 audit linked in the issue comment and the pending W2 stack (#296 → #297 → #299) to establish what remains; Phase 1 is reported done, while Phases 2–4 are open. For a scoped starting point, inspect llm-core/.../OptimizedLLMRuntime.kt, llm-core/.../dsl/TransformerDsl.kt, and llm-core/.../weights/LLMWeightNameResolvers.kt; the issue calls for DSL networks across model families and a unified runner, but does not define a single completion criterion for those phases.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
Context
Currently SKaiNET-transformers has:
- 5+ hand-coded runtimes (LlamaRuntime, Qwen35Runtime, Gemma3nRuntime, ApertusRuntime, VoxtralRuntimes) — each reimplements the forward pass, weight loading, and layer execution
- Tool calling tightly coupled to kllama — the AgentLoop, ToolCallingDemo, and chat modes only exist in the kllama runner. Other models (Gemma, Apertus) cannot use tool calling without duplicating code
- Two execution paths — legacy hand-coded runtimes AND the newer
OptimizedLLMRuntimewith DSL/compute-graph/AOT. LlamaRuntime and ApertusRuntime are already marked deprecated
The goal: converge on one unified pipeline where model definition, weight loading, tokenization, and tool calling are cleanly separated pipeline stages.
Architecture Overview
GGUF/SafeTensors File
|
WeightLoader (parse metadata + tensors)
|
DSL Network Definition (model-specific, declarative)
|
ComputeGraph (DAG)
|
Optimization Pipeline (TransposeElim -> WeightDedup -> LLMFusion -> DCE)
|
ComputeGraphExecutor (fused kernels)
|
InferenceRuntime (unified: forward + generate)
|
TokenizationPipeline (encode/decode, special tokens, byte-level BPE)
|
ChatPipeline (template formatting, tool calling, agent loop)
Status
- Phase 1: DONE (pending merge of the W2 stack #296 → #297 → #299) —
generateUntilStop/GenerateResultpromoted tollm-core(#296),ChatSessionshipped earlier (f42617a), demo/agent CLI + tools extracted from kllama intollm-agent(#296); kllamaMain.ktdispatch is now ~25 thin lines over shared classes. Audit details: https://github.com/SKaiNET-developers/SKaiNET-transformers/issues/49#issuecomment-5255175760 - Phases 2-4: open (out of W2 scope). Note the unified
skainet-cliseed exists but thellm-appsmodules currently fail dependency resolution on develop (empty engine version) — needs a small separate fix.
Phase 1: Decouple Tool Calling from kllama (immediate value)
Problem: Tool calling lives in llm-agent (good) but is wired only through kllama CLI. Other runners can't use it.
Changes:
-
Move AgentLoop's generation into
InferenceRuntimeinterface (llm-core)generateUntilStop()is currently an extension function inllm-agent— promote it or add agenerate()method with stop-token support to the interface- File:
llm-core/.../InferenceRuntime.kt
-
Create
ChatSessionabstraction (llm-agent)- Bundles:
InferenceRuntime+Tokenizer+ChatTemplate+ToolRegistry - Any runner creates a
ChatSessionto get chat/agent/demo modes for free - File: new
llm-agent/.../ChatSession.kt
- Bundles:
-
Extract CLI chat/agent/demo dispatch from kllama Main.kt into shared module
- Currently lines 532-551 of
Main.ktdispatch toToolCallingDemo/AgentCli - This logic should work for any runner that provides
InferenceRuntime+Tokenizer
- Currently lines 532-551 of
Critical files:
llm-core/.../InferenceRuntime.kt— extend interfacellm-agent/.../AgentLoop.kt— already well-abstracted, keep as-isllm-runtime/kllama/.../Main.kt— extract dispatch logicllm-runtime/kllama/.../ToolCallingDemo.kt— move tollm-agentorllm-appsshared module
Phase 2: Unified DSL-Based Model Definition (converge on OptimizedLLMRuntime)
Problem: Each model has a hand-coded runtime. OptimizedLLMRuntime already supports DSL -> graph -> optimized execution, but only some models use it.
Changes:
-
Define DSL networks for all model families:
llamaNetwork(config)— LLaMA/Mistral/Qwen2/3 (standard transformer)qwen35Network(config)— Qwen3.5 (hybrid DeltaNet + full attention)gemmaNetwork(config)— Gemma (GELU, MatFormer FFN, sliding window)apertusNetwork(config)— Apertus (xIELU, ungated MLP, QK-norm)- Each is a pure function returning a
Network<T>from the DSL
-
Unified model loading flow:
detectArchitecture(ggufMetadata) -> ModelFamily ModelFamily.createNetwork(config) -> Network<T> WeightLoader.loadAndMap(file, network) -> weights OptimizedLLMRuntime(network, weights, mode=HYBRID) -> InferenceRuntime -
Remove deprecated hand-coded runtimes once DSL equivalents are validated:
LlamaRuntime->llamaNetwork()+OptimizedLLMRuntimeApertusRuntime->apertusNetwork()+OptimizedLLMRuntime
Critical files:
llm-core/.../OptimizedLLMRuntime.kt— already exists, extendllm-core/.../dsl/TransformerDsl.kt— already has embedding, MHA, SwiGLU, RMSNormllm-core/.../weights/LLMWeightNameResolvers.kt— already maps DSL paths -> GGUF names- New: per-model DSL network definitions
Phase 3: Tokenization as Pipeline Stage
Problem: Tokenization is split between GGUFTokenizer (kllama module), QwenByteLevelBPETokenizer (llm-core), and model-specific code. The byte-level BPE fix we just made shows the fragility.
Changes:
-
Enhance
Tokenizerinterface (llm-core):interface Tokenizer { fun encode(text: String): IntArray fun decode(token: Int): String fun decode(tokens: IntArray): String val eosTokenId: Int val bosTokenId: Int val vocabSize: Int val specialTokens: Set<String> } -
Unified tokenizer factory:
TokenizerFactory.fromGGUF(source)— auto-detects BPE/SentencePiece/WordPieceTokenizerFactory.fromTokenizerJson(json)— HuggingFace format- Returns the correct implementation (byte-level BPE for GPT-2/Qwen, SentencePiece for LLaMA, etc.)
-
Move
GGUFTokenizertollm-coreso all runners can use it without depending on kllama
Phase 4: Unified Runner (single CLI entry point)
Problem: 6 separate CLI apps with duplicated argument parsing, model loading, and dispatch logic.
Changes:
-
Single
skainetCLI that auto-detects model architecture from GGUF metadata:skainet -m model.gguf "prompt" # auto-detect, generate skainet -m model.gguf --chat # auto-detect, chat mode skainet -m model.gguf --demo "What is 2+2?" # auto-detect, tool calling -
Architecture registry:
ModelRegistry.register("llama", ::llamaNetwork) ModelRegistry.register("qwen3", ::qwenNetwork) ModelRegistry.register("gemma", ::gemmaNetwork) -
Auto-detection from GGUF metadata (already exists in
peekGgufMetadata())
Verification
- All existing unit tests pass (
llm-agent,llm-runtime:kllama,llm-core) - Smoke test suite passes (generation + tool calling)
- Basic generation produces identical output for all model families
- Tool calling works for any model that supports ChatML/Qwen/Llama3 templates
OptimizedLLMRuntimein HYBRID mode matches hand-coded runtime output
- Langage dominant
- Kotlin
- Étoiles
- 8
- Forks
- 3
- Merge moyen
- 19 h 45 min
- PR mergées (30 j)
- 38
Préparer son environnement
Ce projet ne fournit ni conteneur de développement, ni Dockerfile, ni guide de contribution : l'installation est à votre charge. Commencez par son README, et consultez notre guide de la première contribution pour les étapes générales.
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de SKaiNET-developers/SKaiNET-transformers
-
documentation good first issue size:xs skill:docs sub-issue
Difficulté 2/5 1-3 heures Accessibilité débutants 78/100
SKaiNET-developers/SKaiNET-transformers#478 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
bug
Difficulté 4/5 3-5 jours Accessibilité débutants 48/100
SKaiNET-developers/SKaiNET-transformers#483 ·
Les mainteneurs répondent en général sous 1 jour
-
coding good first issue size:s skill:kotlin-core sub-issue
Difficulté 4/5 1-2 jours Accessibilité débutants 64/100
SKaiNET-developers/SKaiNET-transformers#477 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
coding good first issue size:s skill:numerics sub-issue
Difficulté 4/5 3-5 jours Accessibilité débutants 55/100
SKaiNET-developers/SKaiNET-transformers#476 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
moonshine stream: the final encoder window is zero-padded and the encoder has no attention maskOuverte
Difficulté 4/5 3-5 jours Accessibilité débutants 25/100
SKaiNET-developers/SKaiNET-transformers#458 ·
Les mainteneurs répondent en général sous 1 jour
Toutes les issues de SKaiNET-developers/SKaiNET-transformers
Issues similaires
-
bug
Difficulté 2/5 1-3 heures Accessibilité débutants 70/100
openbase/planetsudo.engine#107 ·
Les mainteneurs répondent en général sous 1 jour
-
native-cpu: -Wreturn-type in skainet_row_threads.c:150 (worker fn has no return)Peut-être pris @Doomguy-BFG9000 l’a pris aujourd’hui. Ouvertegood first issue size:xs skill:native
Difficulté 1/5 Moins d'une heure Accessibilité débutants 78/100
SKaiNET-developers/SKaiNET#1358 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
enhancement
Difficulté 2/5 1-3 heures Accessibilité débutants 63/100
IBRAHIMDANS/i18nSupportPlus#577 · 3 commentaires ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 72/100
PostHog/posthog-kmp#100 ·
Les mainteneurs répondent en général sous 2 jours
-
Toronto time zone missingOuvertefeature request needs triage
Difficulté 2/5 1-3 heures Accessibilité débutants 65/100
FossifyOrg/Clock#521 ·
Les mainteneurs répondent en général sous 1 jour