You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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 OptimizedLLMRuntime with 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.
Phases 2-4: open (out of W2 scope). Note the unified skainet-cli seed exists but the llm-apps modules 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 InferenceRuntime interface (llm-core)
generateUntilStop() is currently an extension function in llm-agent — promote it or add a generate() method with stop-token support to the interface
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.
Context
Currently SKaiNET-transformers has:
OptimizedLLMRuntimewith DSL/compute-graph/AOT. LlamaRuntime and ApertusRuntime are already marked deprecatedThe goal: converge on one unified pipeline where model definition, weight loading, tokenization, and tool calling are cleanly separated pipeline stages.
Architecture Overview
Status
generateUntilStop/GenerateResultpromoted tollm-core(W2a: #49-P1 substrate — generateUntilStop in llm-core, demo/CLI out of kllama, shared ModelMetadata extraction (#37) #296),ChatSessionshipped earlier (f42617a), demo/agent CLI + tools extracted from kllama intollm-agent(W2a: #49-P1 substrate — generateUntilStop in llm-core, demo/CLI out of kllama, shared ModelMetadata extraction (#37) #296); kllamaMain.ktdispatch is now ~25 thin lines over shared classes. Audit details: Unified Model Pipeline with Decoupled Tool Calling #49 (comment)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 throughkllamaCLI. 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 interfacellm-core/.../InferenceRuntime.ktCreate
ChatSessionabstraction (llm-agent)InferenceRuntime+Tokenizer+ChatTemplate+ToolRegistryChatSessionto get chat/agent/demo modes for freellm-agent/.../ChatSession.ktExtract CLI chat/agent/demo dispatch from kllama Main.kt into shared module
Main.ktdispatch toToolCallingDemo/AgentCliInferenceRuntime+TokenizerCritical 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 modulePhase 2: Unified DSL-Based Model Definition (converge on OptimizedLLMRuntime)
Problem: Each model has a hand-coded runtime.
OptimizedLLMRuntimealready 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)Network<T>from the DSLUnified model loading flow:
Remove deprecated hand-coded runtimes once DSL equivalents are validated:
LlamaRuntime->llamaNetwork()+OptimizedLLMRuntimeApertusRuntime->apertusNetwork()+OptimizedLLMRuntimeCritical 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 namesPhase 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):Unified tokenizer factory:
TokenizerFactory.fromGGUF(source)— auto-detects BPE/SentencePiece/WordPieceTokenizerFactory.fromTokenizerJson(json)— HuggingFace formatMove
GGUFTokenizertollm-coreso all runners can use it without depending on kllamaPhase 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:Architecture registry:
Auto-detection from GGUF metadata (already exists in
peekGgufMetadata())Verification
llm-agent,llm-runtime:kllama,llm-core)OptimizedLLMRuntimein HYBRID mode matches hand-coded runtime output