Buckets:

institutional/skills / institutional-books.md
MatteoCargnelutti's picture
|
download
raw
10.2 kB
metadata
name: institutional-books
description: >-
  Use the Institutional Books family of Hugging Face datasets and models: the
  public-domain book corpus and its metadata, enriched/segmented text, and
  per-page visual elements, plus models for visual-element detection,
  classification, orientation, and topic classification. Use when a task
  involves the Institutional Books corpus, digitized-book text or metadata
  analysis, extracting or classifying figures/charts/music/illustrations from
  scanned pages, or assigning library topics to books.

Institutional Books — datasets & models

A family of Hugging Face assets built from Institutional Books (983K public-domain books, ~242B tokens, digitized from Harvard Library's Google Books participation and refined by the Institutional Data Initiative). Technical reports: arXiv:2506.08300, arXiv:2608.19026, arXiv:2608.18957

Two ideas that drive every decision:

  1. barcode_src is the join key. One book = one barcode. Every dataset carries barcode_src, so you relate them with a join, not a re-download.
  2. The datasets are precomputed model outputs. The topic and visual-element models were already run over the whole corpus and their results stored as columns. Read the field instead of re-running the model. Only run a model on new images or text that isn't already in the corpus.

Pick the right asset

I need to… Use
Book text (original + post-processed OCR) + all metadata dataset institutional-books-hl (large — stream it)
Metadata only (title, author, dates, language, topic, OCR scores…) without downloading text dataset institutional-books-hl-metadata
Structurally segmented text (front/middle/back matter) + refined text stats dataset institutional-books-hl-enriched-text
Figures/charts/music/illustrations already extracted from pages (boxes, labels, orientation, captions, embeddings) dataset institutional-books-hl-visual-elements
A book's high-level topic (already computed) field topic_or_subject_gen in the corpus/metadata datasets
A book's visual elements (already computed) dataset institutional-books-hl-visual-elements
Topic of a new book from its metadata model institutional-books-topic-classifier-bert
Find visual elements on a new page scan model …-visual-elements-detection…-classification…-orientation

Datasets

All under the institutional/ org. Load with the datasets library. See Auth & gating for gated repos.

institutional-books-hl — full corpus

One row per book (~983K). Key fields: barcode_src (primary key), title_src, author_src, date1_src, language_src/language_gen, topic_or_subject_gen, text_by_page_src (original OCR, List[str] by page), text_by_page_gen (post-processed OCR; ~850K books in eng/deu/fra/ita/spa). Large — always stream.

from datasets import load_dataset

ds = load_dataset("institutional/institutional-books-hl", split="train",
                  streaming=True, token=True)  # token=True → uses HF_TOKEN / cached login
for row in ds:
    print(row["barcode_src"], row["title_src"])
    print(row["text_by_page_gen"][0])  # first page, post-processed OCR
    break

institutional-books-hl-metadata — metadata only

Same schema as the corpus minus the text_by_page_* text columns. Use this whenever you don't need the full text — it's far smaller and ungated.

ds = load_dataset("institutional/institutional-books-hl-metadata", split="train")

institutional-books-hl-enriched-text — segmented text

One row per book. barcode_src + frontmatter_gen / middlematter_gen / backmatter_gen (structural segments), processed_middlematter_gen, plus text-quality stats (tokenizability_ratio_gen, bits-per-byte bpb_*, n-gram/word/sentence counts). Use when you need document structure or refined-text quality signals.

institutional-books-hl-visual-elements — extracted visual elements

One row per detected element (10M–100M rows) — the detection→classification→orientation pipeline already run over the corpus. Key fields:

  • id, barcode_src, page_filename_src, bbox_xyxy_gen — where the element is
  • crop_gen — the cropped image
  • detection_confidence_gen
  • classification_gen (+ _confidence_gen, _probs_gen) — matches the split it came from
  • orientation_correction_gen (+ _confidence_gen, _probs_gen)
  • caption_exp, phash_gen, embedding_gen — caption, perceptual hash, vector

Splits are the categories, so select one instead of filtering: music, image_illustration, chart_graph, ex_libris_decorative, artifact, other.

from pathlib import Path

out = Path("music_crops"); out.mkdir(exist_ok=True)
ve = load_dataset("institutional/institutional-books-hl-visual-elements",
                  split="music", streaming=True)  # pick the category you want
for row in ve.take(20):                            # first 20 music scores
    row["crop_gen"].save(out / f"{row['id']}.png")  # unique filename per element (PIL image)
    print(row["id"], row["barcode_src"], row["detection_confidence_gen"])

Models

All under institutional/. Weights via huggingface_hub.hf_hub_download.

institutional-books-topic-classifier-bert (transformers)

mBERT fine-tune. Input: a formatted metadata string. Output: one of 20 Library of Congress top-level classes (SCIENCE, LAW, MEDICINE, HISTORY OF THE AMERICAS, …). This is the source of topic_or_subject_gen — only run it for books not in the corpus.

from transformers import pipeline

pipe = pipeline("text-classification",
                model="institutional/institutional-books-topic-classifier-bert")
text = "Title: A treatise on analytical geometry\nAuthor: Hymers, J.\nYear: 1848\nLanguage: English"
print(pipe(text))  # [{'label': 'SCIENCE', 'score': 0.99...}]  (all fields optional)

Visual-elements pipeline

Three models mirror the visual-elements dataset columns. Run them in order on a new page scan; for corpus pages, read the dataset instead.

1. Detection…-visual-elements-detection (YOLOv26n, ultralytics). Page scan → bounding boxes (single class "visual element").

from huggingface_hub import hf_hub_download
from ultralytics import YOLO

det = YOLO(hf_hub_download("institutional/institutional-books-visual-elements-detection",
                           "weights/best.pt"))
results = det.predict("page_scan.jpg", imgsz=640, conf=0.3, iou=0.2)
boxes = [b.xyxy.tolist()[0] for b in results[0].boxes]  # crop these from the page

2. Classification…-visual-elements-classification (YOLOv26s-cls, ultralytics). A cropped element → one of 5 classes: 0 Artifact · 1 Chart/Graph · 2 Ex Libris/Decorative · 3 Image/Illustration · 4 Music.

cls = YOLO(hf_hub_download("institutional/institutional-books-visual-elements-classification",
                           "weights/best.pt"))
r = cls.predict("crop.jpg", imgsz=640)[0]
print(r.names[r.probs.top1], float(r.probs.top1conf))

3. Orientation…-visual-elements-orientation (EfficientNetV2-M, raw PyTorch state_dict). A crop → rotation correction: 0 upright · 1 rotate_90_clockwise · 2 rotate_180 · 3 rotate_90_counterclockwise. Predictions below 0.99 confidence default to upright.

import torch, torch.nn as nn, torchvision.models as models
from torchvision import transforms
from PIL import Image
from huggingface_hub import hf_hub_download

m = models.efficientnet_v2_m(weights=None)
m.classifier = nn.Sequential(nn.Dropout(0.3, inplace=True),
                             nn.Linear(m.classifier[1].in_features, 4))
m.load_state_dict(torch.load(
    hf_hub_download("institutional/institutional-books-visual-elements-orientation",
                    "weights/weights.pth"), map_location="cpu", weights_only=True))
m.eval()

prep = transforms.Compose([
    transforms.Resize((512, 512)), transforms.CenterCrop(480), transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])])
labels = {0: "upright", 1: "rotate_90_clockwise", 2: "rotate_180", 3: "rotate_90_counterclockwise"}

with torch.no_grad():
    probs = torch.softmax(m(prep(Image.open("crop.jpg").convert("RGB")).unsqueeze(0)), 1)[0]
top = int(probs.argmax())
label = labels[top] if float(probs[top]) >= 0.99 else "upright"

# apply: rotate_90_clockwise → img.rotate(-90, expand=True);
#        rotate_180 → 180; rotate_90_counterclockwise → 90

How they connect

Field suffixes tell you a value's provenance:

Suffix Meaning
_src From the source collection (original bibliographic/OCR data)
_gen Generated by IDI analysis or a model (e.g. topic_or_subject_gen)
_ext Pulled from an external source (e.g. hathitrust_data_ext)
_exp Experimental (e.g. caption_exp)

Join on barcode_src to combine datasets — e.g. filter visual elements by a book's language, date, or topic:

meta = load_dataset("institutional/institutional-books-hl-metadata", split="train")
fr = {r["barcode_src"] for r in meta if r["language_gen"] == "fra"}  # French books

ve = load_dataset("institutional/institutional-books-hl-visual-elements",
                  split="train", streaming=True)
music_in_french = (r for r in ve
                   if r["barcode_src"] in fr and r["classification_gen"] == "Music")

Within the visual-elements dataset, page_filename_src + bbox_xyxy_gen locate an element on its specific page.

Visual pipeline (only for new scans): page → detection (boxes) → crop → classification (5 classes) + orientation (4 classes) → optional caption/embedding. This is exactly what produced the visual-elements dataset columns.

Auth & gating

Set a token that has been granted access, then pass it to the loaders:

export HF_TOKEN="hf_..."          # or: huggingface-cli login

Dependencies

pip install datasets huggingface_hub transformers torch torchvision pillow ultralytics

Xet Storage Details

Size:
10.2 kB
·
Xet hash:
207eda52979cf320628a8eabbf864f6983104e18ce6af16cde7a37e6e096cd20

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.