BLOG

Notes from the workshop.

Writing on AI, data engineering and the infrastructure underneath it — from the founder building Certant. Practical, occasionally opinionated, always from the trenches.

Scaling Internal Knowledge Bases for Mid-Sized Firms
LATEST

Scaling Internal Knowledge Bases for Mid-Sized Firms

Scaling internal knowledge bases for mid-sized firms requires structure, not just software. Learn best practices, productivity gains, and software.

Editorial Team··10 min read
Read the post
Three castles, each sealed inside its own floating glass dome with a Docker whale, illustrating one VM per worktree
Daniel Voyce··10 min read

Running the whole RAG stack on a MacBook, one Colima VM per worktree

What really runs locally on Apple Silicon: a VM per git worktree, a pgvector SIGILL that never showed on OrbStack, and a PaddleOCR segfault we never fixed.

Read the post
Cover image for Missing tables, not the extraction model, explain the accuracy gap
Daniel Voyce··9 min read

Missing tables, not the extraction model, explain the accuracy gap

Two knowledge bases, same corpus, different extraction models, the same 41.8% and zero disagreements. The failing questions all had their answers in tables.

Read the post
Cover image for A 0.6B model was starving on the CPU: moving citation highlighting to the GPU
Daniel Voyce··6 min read

A 0.6B model was starving on the CPU: moving citation highlighting to the GPU

Citation highlighting ate 50 s of a 71 s query on our DGX Spark. The encoder was tiny; the CPU was full. Moving it to the idle GPU: 3.6 s to 0.08 s per chunk.

Read the post
Diagram contrasting the four-model stack with the consolidated Gemma-4 stack, showing OCR at 0.42 s per page against 18 s per page
Daniel Voyce··11 min read

The Gemma-4 experiment: one model for chat, OCR and reranking

One Gemma-4 model runs chat, extraction and reranking on a DGX Spark. OCR stays a dedicated model: consolidated OCR runs 40x slower per page.

Read the post
Grafana dashboard for the DGX Spark stack during the OCR phase of a 50-document benchmark, showing generation at 363 tok/s, prompt prefill peaking at 3.69K tok/s, and 99.4 GiB of 121 GiB unified memory used
Daniel Voyce··11 min read

155 pages of OCR took 37 minutes. The bottleneck was one threading.Lock.

A lock around a single GPU model made OCR serial. Moving GLM-OCR to SGLang took a 155-page PDF to under five minutes. The RunPod and client-side details.

Read the post
Knowledgebase wizard with agreement and payroll export indexed, FDE drawer open
Daniel Voyce··9 min read

Four employees below their legal minimum: the Aruma scenario end to end

A screenshot-led walk through the Aruma pay-compliance run: bind a knowledgebase, ask in plain English, approve one correction, get four names back.

Read the post
PDF visualiser showing the Schedule J salary and allowance rate table with DDSO 1, 1Q, 2 and 2A classification groups, four effective-date column groups, and chunk overlay boxes numbered 5 and 6 on the right panel
Daniel Voyce··11 min read

Five OCR engines and one enterprise agreement: what actually read the rate tables

MinerU, Docling, PaddleOCR, GLM-OCR and Baidu Unlimited-OCR on the same wage schedules. Rowspans, a silent under-extraction bug, and what we run now.

Read the post
Stacked bar chart of the DGX Spark's 121 GiB unified memory pool filled three ways, showing gpt-oss-120B leaving 1-7 GiB free, Qwen3.6 leaving 28-30 GiB and Gemma-4 leaving about 55 GiB
Daniel Voyce··10 min read

Why Qwen3.6 with thinking off became our DGX Spark default

Swapping gpt-oss-120B for Qwen3.6-35B gave back 25 GiB on the GB10, and one per-call reasoning flag took a merge summary from 189 s to 4 s.

Read the post
Certant admin UI in dark mode with the AI FDE drawer open on the right, bound to the Aruma Disability Services EA knowledgebase, showing the greeting and a branch chip reading main
Daniel Voyce··10 min read

An agent with write access to your ontology

Our AI FDE can edit a live data model. The gate around it: a short-lived key scoped to you, three server-enforced tiers, and a signed exposure register.

Read the post
Certant PDF viewer on page 146 of 147, Schedule J minimum hourly rates, DDSO 2 at $21.34
Daniel Voyce··10 min read

Page 146: the number nobody was going to find

Two people paid below a legal minimum buried in a 147-page agreement, found and proved from the page, then fixed with a human signature.

Read the post
Grafana panels during document ingest on the gpt-oss stack
Daniel Voyce··11 min read

The standard stack: gpt-oss-120B and a full RAG pipeline on one box

Four models in 121 GiB of unified memory, 1 to 7 GiB free, and the boot loop that took a 64 GB swapfile to fix. The DGX Spark reference build, warts included.

Read the post
Certant dashboard in Simple mode showing workspace overview cards and the small AI FDE pill in the bottom-right corner
Daniel Voyce··8 min read

An engineer in a drawer: 274 seconds to a working ontology

Palantir sends a forward deployed engineer. We ship one in a drawer: 21 July 2026, it built a working ontology for 1.5 credits, failed three of five tasks.

Read the post
Certant KB settings, Advanced section, showing the Strata data model toggle card
Daniel Voyce··12 min read

Building a data model from PDFs instead of designing one

Certant Strata turns the tables inside a PDF corpus into a versioned data model. How the pipeline works, and the four ways it broke at corpus scale.

Read the post
Line chart of aggregate tokens per second against concurrent requests for Qwen3.6 with thinking off and Gemma-4, with saturation knees marked at 32 and 64 concurrent requests.
Daniel Voyce··9 min read

Most people tuning local LLMs optimise the wrong half of the problem

A full 50-document ingest pinned the GPU at 96% for 38 minutes, on prefill, not decode, while the celebrated decode levers barely moved throughput.

Read the post
Bar chart of unified memory used by three model stacks against a 121 GiB ceiling: gpt-oss-120B leaves 1 to 7 GiB free, Qwen3.6 leaves 28 to 30 GiB, Gemma-4 leaves about 55 GiB idle
Daniel Voyce··7 min read

\"128GB of VRAM\" is the most misread spec on the DGX Spark

The DGX Spark's 128GB is one pool shared by CPU and GPU, not VRAM: the memory budget, the OOM spike, and what to set.

Read the post
Slide reading "Not a chatbot. Their company's intelligence." with four cards: grounded in your ontology, every answer cited, 100% on the box (on-device and air-gapped capable, no data egress), working on day one
Daniel Voyce··10 min read

What air-gapped actually means: every phone-home in the stack, audited

Ten outbound-call vectors in our own stack, the two that needed code, and the tcpdump proof that a locked-down box still answers.

Read the post
Timeline infographic of seven optimisation steps on a DGX Spark, each showing a before and after value, running from "won't boot" to a batched ceiling of 1,000 to 2,800 tokens per second.
Daniel Voyce··8 min read

Seven levers that took a DGX Spark from won't boot to 2,800 tokens a second

Seven config changes took my DGX Spark from OOM-killing itself on boot to 2,800 tokens a second, measured before and after.

Read the post
Verdict cards for the three models: Qwen3.6-35B at 2,805 tok/s batched with 28-30 GiB free, Gemma-4 26B consolidating chat, OCR and rerank, and gpt-oss-120B at 2,621 tok/s but only 1-7 GiB free
Daniel Voyce··9 min read

Which LLM should you run on a DGX Spark? gpt-oss-120B vs Qwen3.6-35B vs Gemma-4 26B

Three model stacks, one DGX Spark, a month of benchmarks: why Qwen3.6-35B with thinking off beats Gemma-4 26B and gpt-oss-120B on this box.

Read the post
Cover image for Asking for JSON halved our extraction recall. JSON Lines fixed it.
Daniel Voyce··11 min read

Asking for JSON halved our extraction recall. JSON Lines fixed it.

A graph-extraction regression traced to output shape: a closed JSON object tells the model to stop early. Removing the enclosing array recovered 2.7x.

Read the post
Bar chart comparing single-stream and 128-request batched throughput for gpt-oss-120B, Qwen3.6-35B and Gemma-4 26B on a DGX Spark, with 42.7x, 23.4x and 22x gain badges
Daniel Voyce··8 min read

Stop chat-testing your DGX Spark

A single chat window is the one benchmark the DGX Spark is built to lose. The two hardware numbers behind that, and the 22-43x you get back from batching.

Read the post
My FrankenNAS setup
Daniel Voyce··3 min read

Getting vLLM v0.9.2 working on CUDA 12.4 on QNAP (Driver 550.76)

Getting vLLM v0.9.2 running on CUDA 12.4 with an older QNAP NAS and Nvidia driver 550.76 using a custom Docker build.

Read the post
Photo by Fabrizio Chiagano
Daniel Voyce··7 min read

Moving from Ollama to vLLM: Finding Stability for High-Throughput LLM Serving

An engineer's journey from using Ollama to vLLM for running large language models locally, exploring the trade-offs between convenience and production-grade stability for high-throughput inference.

Read the post
MindLattice Logo
Daniel Voyce··3 min read

Overdue update: The launch of MindLattice

An overview of MindLattice, a platform addressing data engineering challenges in AI transformation and serving underserved industries.

Read the post
Abstract visualization of data graph connections
Daniel Voyce··7 min read

GraphRAG Is the Logical Step From Rag — So Why the Sudden Hype?

GraphRAG builds on RAG by using graph structures to organize data relationships, providing LLMs with richer context while avoiding hallucinations.

Read the post
Autogluon architecture showing multi-layer stacking for forecasting
Daniel Voyce··11 min read

Revolutionising Machine Learning: Achieving Top 4% in Kaggle with AutoGluon in Just 7 Lines of Code

Discover how AutoML and AutoGluon can achieve competitive Kaggle rankings with just seven lines of Python code, automating feature engineering and model selection.

Read the post
GPU and data processing technology
Daniel Voyce··9 min read

Data Engineering: Fast Spatial Joins Across ~2 Billion Rows on a Single Old GPU

Explore GPU-accelerated spatial joins processing 2.3 billion rows on a consumer GTX 1060, comparing Parquet vs ORC performance for large-scale geospatial data.

Read the post
Colorful abstract shapes representing GPU computing and data processing
Daniel Voyce··8 min read

GPU Data Engineering, CSV to Parquet & ORC using Dask & RAPIDS.ai

Converting large CSV files to Parquet and ORC formats using Dask and RAPIDS.ai on consumer GPU hardware, with performance benchmarks and optimization strategies.

Read the post
LiDAR and satellite imagery for reforestation verification
Daniel Voyce··7 min read

What is dMRV and how does it relate to Carbon Accounting?

How digital measurement, reporting and verification (dMRV) is transforming carbon accounting through automation, blockchain tokenization, and accessible audit tools.

Read the post
Green field landscape with blue sky
Daniel Voyce··3 min read

TYMLEZ Releases 2 Open-Source Guardian Policies in time for COP27

TYMLEZ releases two open-source Guardian policies for carbon emissions tracking and reduction on the Hedera network, enabling dMRV implementations ahead of COP27.

Read the post
TYMLEZ and Hedera Guardian release announcement
Daniel Voyce··2 min read

TYMLEZ releases AWS & GCP Terraform setup for the Hedera Guardian

TYMLEZ releases infrastructure-as-code for deploying Hedera Guardian on AWS and GCP using Terraform, with autoscaling and production-ready Kubernetes setup.

Read the post

These posts first appeared on Dan's Medium. They're republished here in full, with the originals credited as canonical.