Skip to content

Latest commit

 

History

8 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Book Summarizer

Batch-summarize .txt books with Ollama and a local LLM, writing one row per book to an Excel spreadsheet (.xlsx).

The model reads the full text of every book — never a truncated excerpt. Books that fit the context window are summarized in one pass; bigger books are split into passages, each summarized separately, and the passage summaries are merged into the final summary.

All prompts are in French and the model is asked to produce a ~500-word French summary plus a score from 1 to 10 (e.g. Note : 8/10) for each book.

Features

  • No truncation — the whole book is always fed to the model:
    • fits in context → single-shot summary;
    • too big → chunk-compact: each passage summarized in 200–300 French words, then merged into the final summary.
  • Plain-text replies — the model answers in free-form French prose (no JSON, no fragile structured parsing).
  • Resumable — the output spreadsheet is parsed on startup; books already processed are skipped automatically, previously failed books are retried.
  • Per-book robustness — each model call retries up to 3 times (empty or degenerate replies included), and results are saved to the spreadsheet after every book.
  • Progress on screenFile + summary per book, [CHUNKED: N passages] marker, and a --verbose mode with timing and raw replies.
  • Stop anytime — press ESC in the console to abort the run gracefully (works even mid-call; Ctrl-C also works). The in-flight book is not recorded and is retried on the next run.

Requirements

  • Python 3.10+
  • An Ollama server running locally (default http://127.0.0.1:11434)
  • The Python client and the spreadsheet writer: pip install ollama openpyxl
  • A model pulled, e.g.:
ollama pull mistral-nemo:12b

The default model is mistral-nemo:12b (12B, ~7 GB quantized, native 128k context). Any other model can be used with --model.

Installation

git clone <your-repo-url>
cd <your-repo>
pip install ollama openpyxl

Usage

python summarize_books.py <folder> [options]

<folder> is scanned recursively for *.txt files.

Examples:

# Summarize every book in the folder
python summarize_books.py "books/Africa"

# Only the last 5 books (in sorted order)
python summarize_books.py "books/Africa" -n 5

# Show per-call timing and raw replies
python summarize_books.py "books/Africa" -n 5 --verbose

Re-running the same command skips books already in the spreadsheet and picks up where the previous run stopped. Books that previously errored are attempted again.

Reviewing summaries

review_summaries.py walks every book whose review column is still empty, one at a time, showing the file path and the stored summary:

python review_summaries.py                 # review book_reviews.xlsx
python review_summaries.py -o out.xlsx -e out_errors.csv

For each book press a single key (no Enter needed): 09 to rate it, e to mark it as a bad entry, or q to quit. The book title and summary are read aloud (Windows TTS, French voice when installed); pressing any key stops the reading — use --no-tts to disable. Ratings are stored in the review column (added to the spreadsheet on first use); e removes the row from the spreadsheet and appends it to the error file (book_reviews_errors.csv by default) with the date, so bad entries stay trackable. Rows whose reply starts with [ERROR] are moved to the error file automatically on startup. Progress is saved after every entry, so the next run resumes where you left off. summarize_books.py preserves the review column on every rewrite.

Options

Option Default Description
folder Folder containing the books (.txt, scanned recursively)
--model mistral-nemo:12b Ollama model to use
--output book_reviews.xlsx Output spreadsheet path
--num-ctx 49152 Context window in tokens (0 = auto-detect from the model)
--chunk-size 45000 Max tokens per passage when a book is chunked (kept below --num-ctx automatically)
-n, --limit 0 Process at most N books, in sorted order (0 = all)
--verbose off Print per-call timing, token counts and raw replies
--no-prompt-cache off Disable ollama's prompt cache (avoids CPU churn from KV state saves between chunks)
--timeout 600 Per-call timeout in seconds

Output

Excel spreadsheet (.xlsx) with two columns:

file path llm output
books/FR Nouvelles/Żywila Powiastka z Dziejów Litewskich.txt Le livre "Żywila" est une légende lithuanienne ... Note : 8/10

The llm output cell holds the model's raw reply (French summary + Note : X/10). On screen, each result is printed as File + Summary, prefixed with [CHUNKED: N passages] when the book was chunked. Failures are stored as [ERROR] <reason> and are retried on the next run. The workbook is rewritten (atomically) after every book, so progress survives a crash; --validate prunes bad rows from the file.

How it works

  1. Skip already-done books — the output spreadsheet is read first; rows with a real reply are skipped, [ERROR] rows are retried.
  2. Read the book (*.txt, UTF-8 with fallback).
  3. Single-shot or chunked:
    • if the estimated token count fits in --num-ctx (minus a 2500-token answer reserve), the whole text goes in one call;
    • otherwise it is split on paragraph boundaries into passages of up to --chunk-size tokens. Each passage is summarized (200–300 words, French, CHUNK_SYSTEM_PROMPT), then all passage summaries are merged into the final ~500-word summary + score (MERGE_SYSTEM_PROMPT).
  4. Length correction — if the final summary is under 350 words, one expansion pass asks for a longer one.
  5. Write — the row is added to the workbook and saved immediately.

Every model call retries up to 3 times with a French corrective prompt when the reply is empty or degenerate (e.g. shorter than 50 words for a passage), and replies are capped at 1200 tokens (num_predict) so a runaway generation can never hang a run.

VRAM / context notes (16 GB GPUs)

The KV cache is the VRAM driver, not the chunk size:

  • Default --num-ctx 49152 ≈ 7.9 GB of f16 KV cache + ~7 GB weights ≈ fits 16 GB with headroom; at this setting the whole model stays on the GPU (40–41/41 layers, verified in the ollama logs).
  • --chunk-size can go up to almost --num-ctx (≈46.6k tokens at the default) with no extra VRAM cost.
  • Raising --num-ctx beyond ~64k starts offloading layers to CPU (much slower) and, past ~96k, can crash the ollama runner — which looks like the program hanging. --timeout bounds how long a hung call waits.
  • To halve the KV cache so more layers fit on the GPU, restart the ollama server with OLLAMA_KV_CACHE_TYPE=q8_0 (per-request cache_type is ignored by some ollama builds).

Troubleshooting

Symptom Fix
ModelNotFoundError / model not found ollama pull mistral-nemo:12b (or your --model)
Very slow, or "stuck" on a large book Lower --num-ctx (e.g. 49152) or restart ollama with OLLAMA_KV_CACHE_TYPE=q8_0; check ollama list / GPU usage
High CPU churn between passages Add --no-prompt-cache (ollama saves/evicts GBs of KV state between chunk requests by default)
A call appears to generate forever Fixed: replies are capped at 1200 tokens (num_predict); re-run and the spreadsheet resume skips finished books
A book shows [ERROR] in the spreadsheet It will be retried automatically on the next run; use --verbose to see the raw failure
Re-run skips too many books Rows starting with [ERROR] are never skipped — only successful replies are

License

This project is licensed under the GNU General Public License v3.0. See the LICENSE file for details.

About

Batch-summarize .txt books with Ollama and output the results in a csv file.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages