★ Reading this for free? Get 20 structured AI courses + per-chapter AI tutor — the first chapter of every course free, no card.Start free in 30 seconds
Tutorials

Local NotebookLM Alternative: PDF to a 2-Host Podcast

September 13, 2026
11 min read
LocalAimaster Research Team

Want to go deeper than this article?

Free account unlocks the first chapter of all 25 courses — RAG, agents, MCP, voice AI, MLOps, real GitHub repos.

📚AI Learning Path

Go from reading about AI to building with AI 20 structured courses. Hands-on projects. Runs on your machine. Start free.

Start free
Or own it for life — Lifetime $149, pay once

Short answer: run Open Notebook for the notebook, Ollama for the script, and a local OpenAI-compatible TTS server for the voices — then set Open Notebook's TTS provider to openai_compatible with a base URL of http://host.docker.internal:8969/v1 instead of an OpenAI key. That one field is the difference between a "local" notebook that quietly ships your dialogue to a cloud TTS vendor and one where a confidential PDF becomes a two-host audio episode without a packet leaving the box.

If you have already installed Open Notebook, got Ollama answering questions about your documents, and then found the podcast button demanding an ElevenLabs or OpenAI key — skip to Step 2. That is the exact wall this page exists to get you over.


The Wall Everyone Hits

The language model and the voice model are two different providers in Open Notebook, and only the first one has a native Ollama option.

Open Notebook (lfnovo/open-notebook) is the closest open-source thing to NotebookLM that actually ships the Audio Overview, not just the chat. As of our GitHub API check on 18 August 2026 it sits at 37,003 stars, MIT-licensed, created 21 October 2024, last pushed 16 August 2026, with v1.14.0 as the latest tagged release (21 July 2026). It is genuinely maintained, which is more than can be said for some of the alternatives.

Its podcast pipeline is real and well-built: episode profiles, speaker profiles, an outline stage, a dialogue-writing stage, per-speaker synthesis, then mixing. But the provider model splits into services — language, embedding, text-to-speech, speech-to-text — and the setup guides all cover the first two. So people wire up Ollama, watch chat work beautifully, hit Generate Podcast, and get told to add an API key.

The instinct at that point is to look for an "Ollama TTS" option. There isn't one, and there never will be: Ollama has no /v1/audio/speech endpoint. It serves language models and embeddings. Text-to-speech is a different piece of software entirely.

What Open Notebook does have is an openai_compatible provider with its own per-service base URLs. That provider does not care whether OpenAI is on the other end. Anything that speaks /v1/audio/speech will do — including a container running on your own laptop.


Reading articles is good. Building is better.

Free account = the first chapter of all 25 courses, with a per-chapter AI tutor. No card.

The Stack

Three containers, three ports, zero API keys.

PieceWhat it doesPortProvider setting in Open Notebook
Open Notebook (v1.14.0)Notebook, RAG, podcast pipeline8502 / 5055
OllamaWrites the outline and dialogue; embeds your sources11434ollama (native)
Speaches or Kokoro-FastAPISpeaks each line8969 / 8880openai_compatible

Speaches is the one Open Notebook's own docs use, so it is the path of least resistance. Kokoro-FastAPI is the alternative if you already run one — same Kokoro-82M model underneath, same OpenAI surface, different port and a different model name string. Either works; the config differs by two fields.


Step 1: The Local Brain

Pull one chat model and one embedding model, then add Ollama as a credential — Open Notebook needs both, and the embedding model is the one people forget.

ollama pull qwen3          # the script writer
ollama pull mxbai-embed-large   # source search / RAG

Those two are the models Open Notebook's Ollama documentation recommends by name (it also lists gemma3, phi4 and deepseek-r1 as alternatives for the language slot, and nomic-embed-text as a lighter embedding option). Then in Settings → API Keys, add an Ollama credential pointing at http://host.docker.internal:11434 if Open Notebook is in Docker, or http://localhost:11434 if you run it from source.

Two gotchas worth knowing before they cost you an hour:

  • The model name must match ollama list exactly. Open Notebook's docs call this out specifically — qwen3:32b works, qwen3-32b does not.
  • Turn the worker down to one task. Open Notebook runs background jobs with a default concurrency of 5. On a single-GPU or CPU-only box that means five requests fighting over one model. Set OPEN_NOTEBOOK_WORKER_MAX_TASKS=1 in the environment: block of your compose file — the variable is read at worker launch, not by the app, so putting it in .env alone may not take effect.

New to Ollama itself? Our complete Ollama guide covers the model-tag and memory basics this step assumes.


Step 2: The Local Voice

This is the load-bearing step: run a container that implements /v1/audio/speech, and Open Notebook will treat it as if it were OpenAI.

Open Notebook's own docs/5-CONFIGURATION/local-tts.md documents this route — it is supported, not a workaround. The compose file from those docs:

services:
  speaches:
    image: ghcr.io/speaches-ai/speaches:latest-cpu
    container_name: speaches
    ports:
      - "8969:8000"
    volumes:
      - hf-hub-cache:/home/ubuntu/.cache/huggingface/hub
    restart: unless-stopped

volumes:
  hf-hub-cache:

Start it and pull the voice model (~500MB):

docker compose up -d
docker compose exec speaches uv tool run speaches-cli model download speaches-ai/Kokoro-82M-v1.0-ONNX

Prove it works before you touch Open Notebook. If this curl produces a playable file, the hard part is done:

curl "http://localhost:8969/v1/audio/speech" -s \
  -H "Content-Type: application/json" \
  --output test.mp3 \
  --data '{
    "input": "Hello! Local TTS is working.",
    "model": "speaches-ai/Kokoro-82M-v1.0-ONNX",
    "voice": "af_bella"
  }'

Note the :latest-cpu tag. This stage does not need a GPU. Kokoro-82M is an 82-million-parameter model; Open Notebook's docs put the recommended spec for the TTS container at 4+ CPU cores and 4GB of RAM. There is a :latest-cuda image if you want it faster, and Kokoro on a GPU runs many times realtime — but a two-host episode is a batch job you walk away from, not a live conversation, so CPU is a perfectly reasonable default. If you want the deeper comparison of what these servers cost in memory, our Kokoro-FastAPI walkthrough has the verified figures for both images.

Using Kokoro-FastAPI instead? Two fields change: the base URL becomes http://host.docker.internal:8880/v1 and the model name becomes the literal string kokoro. Voice IDs (af_bella, am_adam, bf_emma…) are the same Kokoro set either way. Our Kokoro TTS setup guide covers the voice list.


Own it instead of renting it

Run this on your own machine and stop paying every month

Pay once and keep it. No renewal, no per-token bill, and nothing you feed it ever leaves your hardware.

Step 3: Wire It Up

Add an OpenAI-Compatible credential whose TTS URL points at your container, then register a TTS model with provider openai_compatible. Both halves are required — the credential alone does nothing until a model uses it.

Credential — Settings → API Keys → Add Credential → OpenAI-Compatible:

FieldSpeachesKokoro-FastAPI
TTS base URL (Docker, macOS/Windows)http://host.docker.internal:8969/v1http://host.docker.internal:8880/v1
TTS base URL (Docker, Linux)http://172.17.0.1:8969/v1http://172.17.0.1:8880/v1
TTS base URL (from source)http://localhost:8969/v1http://localhost:8880/v1
API keyleave blank, or any placeholdernot-needed

Then hit Test Connection. The credential dialog lets you set per-service URLs — LLM, embedding, TTS, STT — so you can leave the LLM slot empty and only fill TTS, which is exactly what you want here since Ollama handles the language side natively.

Model — Settings → Models → Add Model, in the Text-to-Speech section:

FieldSpeachesKokoro-FastAPI
Provideropenai_compatibleopenai_compatible
Model Namespeaches-ai/Kokoro-82M-v1.0-ONNXkokoro
Display NameLocal TTSLocal TTS

The model name is the single most common failure. Open Notebook passes it straight through to the server, and the server rejects anything it does not recognise. If you get "model not found," run curl http://localhost:8969/v1/models and copy the string it returns, character for character.

There is also a deprecated environment-variable route — OPENAI_COMPATIBLE_BASE_URL_TTS=http://host.docker.internal:8969/v1 in your compose environment: block. It still functions, and Open Notebook's docs still show it, but they mark it deprecated in favour of the Settings UI. Use the UI unless you are scripting a deployment.


Step 4: Generate the Episode

Upload the PDF as a source, pick a two-speaker episode profile, assign one voice per speaker, generate. The pipeline from here is Open Notebook's, and it is worth understanding because it explains the quality ceiling.

The project ships preset episode profiles. For the NotebookLM-style two-host feel, the closest presets are:

ProfileSpeakersFeel
Expert Interview2Host asks, expert answers — closest to NotebookLM
Debate Format2Two positions, deliberate disagreement
Panel Discussion3-4Multiple perspectives
Solo Explanation1One friendly narrator
Academic Presentation1One expert, lecture tone

Each speaker profile gets a TTS model and a voice. Give speaker 1 af_bella and speaker 2 am_adam and you have a woman-and-man pair; bf_emma and bm_george gives you the British version. Per-speaker model overrides are supported, so nothing stops you mixing servers.

Open Notebook's docs also give the pipeline and its own time budget: content analysis (~1 min) → outline (2-3 min) → dialogue writing (2-3 min) → audio synthesis, 3-5 min per speaker → mixing (1-2 min), for a stated total of 10-20 minutes for a typical episode. Two caveats we want to be straight about: those are the project's figures, and they describe a cloud-model configuration. Swapping in a local Ollama model makes the three text stages track your own hardware, and swapping in a CPU TTS container changes the synthesis stage. We have not run this end to end on a single 12GB card, so we are not going to quote you a wall-clock number or a peak-VRAM figure we did not measure. What we can tell you is where the time goes and what to watch: docker stats on the TTS container during the synthesis stage, and ollama ps during the outline and dialogue stages.

On source volume, the docs' own advice is 3-5 sources per podcast, and it is good advice. A 30-page PDF plus your own notes produces a focused episode. Twelve sources produces a rambling one.


The Better-Voices Route

If per-line Kokoro is not conversational enough for you, use Open Notebook to write the script and VibeVoice to perform it — one pass, both hosts, still offline.

The structural limit of the in-app route is that each speaker turn is synthesised in isolation and the results are stitched. That gives you two clean voices alternating. It does not give you the overlap, interruption and reaction that make NotebookLM's hosts sound like people rather than a table read.

VibeVoice is the only open-weights model we know of that generates multi-speaker conversation in a single pass, holding voice identity across a long runtime. So:

  1. Generate the episode in Open Notebook with a two-speaker profile.
  2. Use Export Transcript to get the script out.
  3. Reformat as Speaker 1: / Speaker 2: lines and run it through VibeVoice.

The trade-off is honest and it is not small. VibeVoice-1.5B runs on an 8GB card; the better-sounding 7B "Large" needs roughly 20GB, and Microsoft pulled its weights from Hugging Face in September 2025, so the 7B now comes from community mirrors. Microsoft's own model card also asks people not to use it commercially without further testing, and its outputs carry an audible AI disclaimer plus a watermark. Everything is MIT-licensed — Microsoft withdrew distribution, not permission — but you should know all of that before you build a workflow on it. Our VibeVoice setup guide covers the mirror situation and VRAM tiers in detail.

You lose the one-click convenience. You gain a conversation that sounds like one.


What This Setup Cannot Do

Four things worth knowing before you commit an evening.

  1. The voices will not match NotebookLM. Open Notebook's own local-vs-cloud table in local-tts.md rates local TTS quality "Good" against cloud's "Excellent", and local voices as "Limited" against cloud's "Many options" — the project is not overselling this, and neither will we. In our reading the line-by-line synthesis architecture caps the realism more than the model does. Either way: set expectations at "two clear narrators," not "two friends riffing."
  2. Three services means three failure modes. When generation fails, the useful first move is to check each layer independently: curl http://localhost:11434/api/tags for Ollama, curl http://localhost:8969/v1/models for the TTS server, then docker compose logs for Open Notebook itself. From inside the Open Notebook container, docker exec -it open-notebook curl http://host.docker.internal:8969/v1/models tells you whether the problem is the server or the Docker networking between them.
  3. Linux Docker networking is the usual culprit. host.docker.internal is a macOS and Windows convenience. On Linux use the bridge IP 172.17.0.1, or run with --network host and use localhost.
  4. "Offline" needs one online session first. The Docker images, the Ollama models and the Kokoro ONNX weights all have to be downloaded once. After that the stack genuinely runs with the network unplugged — which is the entire point if your PDFs are client, legal or medical documents.

For the document-Q&A half of the workflow without the audio, chat with your PDFs locally covers the lighter-weight tools, and private AI knowledge base covers the same idea at team scale. If you are producing an actual show rather than research briefings, local AI podcast production is the editing-side companion, and best local TTS models compares the voice engines head to head.


Sources

  • lfnovo/open-notebook — repository metadata (37,003 stars, MIT, pushed 16 Aug 2026) and release v1.14.0, both read from the GitHub API on 18 August 2026
  • Open Notebook documentation — docs/5-CONFIGURATION/local-tts.md (Speaches compose file, port 8969, model download, credential fields), docs/5-CONFIGURATION/openai-compatible.md (per-service base URLs, deprecated env vars, model-name rules), docs/5-CONFIGURATION/ollama.md (recommended models, tag-format gotcha), docs/3-USER-GUIDE/creating-podcasts.md (episode profiles, pipeline stages and time budget, source-count advice)
  • Speaches — OpenAI-compatible TTS/STT server used in Open Notebook's documented local route
  • remsky/Kokoro-FastAPI — the alternative OpenAI-compatible TTS server (Apache 2.0)
  • Microsoft VibeVoice model card and repository — licence, weights availability and safety notes, as documented in our own VibeVoice setup guide

FAQ

🎯
AI Learning Path

Go from reading about AI to building with AI

20 structured courses. Hands-on projects. Runs on your machine. Start free.

Or own it for life — Lifetime $149 $599, pay once

Liked this? 25 full AI courses are waiting.

From fundamentals to RAG, agents, MCP servers, voice AI, and production deployment with real GitHub repos. First chapter free, every course.

Reading now
Join the discussion

LocalAimaster Research Team

Creator of Local AI Master. I've built datasets with over 77,000 examples and trained AI models from scratch. Now I help people achieve AI independence through local AI mastery.

Build Real AI on Your Machine

RAG, agents, NLP, vision, and MLOps - chapters across 25 courses that take you from reading about AI to building AI.

Want structured AI education?

25 courses, 519+ chapters, from $9. Understand AI, don't just use it.

AI Learning Path

Comments (0)

No comments yet. Be the first to share your thoughts!

Is there an open-source NotebookLM that also makes the podcast, not just chat?

Yes — Open Notebook (lfnovo/open-notebook, 37,003 stars, MIT, created October 2024, last pushed 16 August 2026 per the GitHub API) has a full podcast pipeline with episode profiles, speaker profiles, outline generation, dialogue writing and mixdown. The part people get stuck on is that its shipped TTS provider list is cloud-first. The fix is the openai_compatible provider: point its TTS base URL at a local server that implements /v1/audio/speech and the audio stage never touches the internet.

Does Open Notebook actually support a local TTS server, or is that a hack?

It is documented, just buried. Open Notebook's own docs/5-CONFIGURATION/local-tts.md walks through running Speaches in Docker on port 8969, downloading speaches-ai/Kokoro-82M-v1.0-ONNX, then adding an OpenAI-Compatible credential under Settings → API Keys with a TTS base URL of http://host.docker.internal:8969/v1. You then add a model with provider openai_compatible and the model name exactly as the server expects. There is also a deprecated environment variable, OPENAI_COMPATIBLE_BASE_URL_TTS, that does the same thing.

Can I use Ollama for the TTS as well as the chat model?

No. Ollama does not serve /v1/audio/speech — it has no text-to-speech endpoint at all. Open Notebook has a native Ollama provider for the language model and embeddings, and a separate openai_compatible provider for TTS. Those are two different servers on two different ports: Ollama on 11434 for the script, Speaches or Kokoro-FastAPI on 8969 or 8880 for the voices. That split is why so many "fully local NotebookLM" guides stop halfway.

Will the local voices sound as good as NotebookLM's hosts?

Honestly, no — not from Kokoro in a per-line synthesis pipeline. Open Notebook synthesises each speaker turn separately and mixes them, so you get two clean voices reading alternating lines rather than two people talking over each other. Kokoro sounds good line by line; what it cannot do is the interruption and overlap that make NotebookLM feel like a real conversation. If that gap matters more to you than one-click convenience, generate the script in Open Notebook, export the transcript, and synthesise it in one pass with VibeVoice instead.

How long does an episode take to generate on one machine?

Open Notebook's own documentation budgets 10-20 minutes end to end for a typical episode: about a minute of content analysis, 2-3 minutes for the outline, 2-3 minutes for dialogue writing, 3-5 minutes of audio synthesis per speaker, and 1-2 minutes of mixing. Those are the project's figures for a cloud-model setup. Running the language model locally on Ollama makes the first three stages slower in proportion to your hardware, and the audio stage faster or slower depending on whether your TTS server has a GPU. We have not benchmarked the full pipeline on a single 12GB card, so treat any single number you see quoted for it — including ours — as unmeasured until you time your own run.

Ready to Go Beyond Tutorials?

20 structured courses with hands-on chapters - build RAG chatbots, AI agents, and ML pipelines on your own hardware.

Bonus kit

Ollama Docker Templates

10 one-command Docker stacks for local models — get Ollama and your TTS server running side by side in minutes. Included with paid plans, or free after subscribing to both Local AI Master and Little AI Master on YouTube.

See Plans →

Was this helpful?

📅 Published: September 13, 2026🔄 Last Updated: September 13, 2026✓ Manually Reviewed
LM

Written by the Local AI Master Team

The team behind Local AI Master

We build Local AI Master around practical, testable local AI workflows: model selection, hardware planning, RAG systems, agents, and MLOps. The goal is to turn scattered tutorials into a structured learning path you can follow on your own hardware.

✓ Local AI Curriculum✓ Hands-On Projects✓ Open Source Contributor
📚
Free · no account required

Grab the AI Starter Kit — career roadmap, cheat sheet, setup guide

No spam. Unsubscribe with one click.

🎯
AI Learning Path

Go from reading about AI to building with AI

20 structured courses. Hands-on projects. Runs on your machine. Start free.

Or own it for life — Lifetime $149 $599, pay once
Free Tools & Calculators