Blog
media runJun 7, 2026/blog/earnings-media-transcript-dataset

Preparing 189 Earnings Calls Into AI-Ready Media Exports

How Alys materialized Git LFS audio, paired transcripts, validated MP3s, and exported 122,376 records from a messy speech dataset.

189

audio files

9.66M

tokens parsed

20,396

canonical chunks

0

critical diagnostics

Date: June 7, 2026 Slug: /blog/earnings-media-transcript-dataset Command: npx --yes alys-akusa@latest prepare . --yes --workspace ~/Alys Final output: prepared/56b9a700be3d

The problem with speech corpora

Earnings calls are a goldmine for financial NLP, speech recognition benchmarking, and retrieval-augmented generation. They contain spontaneous executive speech, analyst Q&A, forward-looking statements, and dense financial jargon. But turning raw earnings recordings into a usable ML dataset is not a matter of ls *.mp3 > manifest.txt.

The real problems start where most blog posts end.

You have audio files checked out from Git that might be Git LFS pointers, not MP3s. You have transcripts scattered across directories with inconsistent naming. You have no timestamps, so you cannot align text chunks to audio intervals. You have no rights metadata, so you do not know which files are safe to train on. And you have almost ten million tokens of text that need chunking, deduplication, validation, and export into six different shapes for six different downstream workflows.

This post is the full engineering story of what that preparation run involved, why the numbers matter, and why a 77/100 media readiness score with zero critical errors is still a blocker for some use cases.

TL;DR

The run worked. The dataset is useful. It is not finished.

Result

Result

0 Git LFS pointers remaining

01

Meaning

The media files were real MP3s, not placeholder text files

Result

189 audio files

02

Meaning

The corpus had a meaningful speech component

Result

100% transcript coverage

03

Meaning

Every audio file had a transcript sidecar

Result

9,662,746 tokens parsed

04

Meaning

The text corpus was large enough to stress real preparation behavior

Result

20,396 canonical chunks

05

Meaning

Deduplication produced a clean retrieval/training base

Result

122,376 primary records

06

Meaning

Multiple export profiles were generated from the accepted chunks

Result

77/100 media readiness

07

Meaning

Media can be inspected, but governance is incomplete

Result

431 warnings

08

Meaning

The run succeeded, but human review is still required

The key lesson: Alys does not only write exports. It tells you which exports are ready, which are risky, and what has to be fixed before the dataset deserves to influence a model.

A quick recap: the final numbers

snippet
[VALIDATE] 0 Git LFS pointer files remaining
[PAIR]     189 audio files, 100% transcript coverage
[PARSE]    801 documents, 9,662,746 tokens
[CHUNK]    22,306 created, 20,396 accepted
[EXPORT]   122,376 primary records written
[MEDIA]    readiness 77/100, 0 critical diagnostics
  • 990 files indexed
  • 801 documents parsed
  • 9,662,746 tokens parsed
  • 22,306 chunks created
  • 20,396 canonical chunks accepted
  • 122,376 total exported records
  • 189 audio files
  • 100% transcript coverage
  • 77/100 media readiness
  • 0 critical media diagnostics
  • 431 warnings

The pipeline succeeded technically. No LFS pointers survived validation. Every audio file found its transcript. No media file was blocked. The text exports are clean and ready.

But the media corpus is still marked needs review. Rights metadata, timestamping, and redaction handling are not optional extras if this becomes training data. They are prerequisites.

What Alys is (and what it is not)

Alys is a terminal-native data preparation system. You point it at a messy source directory, and it produces structured exports with provenance, diagnostics, and readiness scores.

Writing a JSONL file is trivial. Any Python script can do that in ten lines. The hard parts are the ones most pipelines skip:

  • Knowing whether the "MP3" in your checkout is real audio or a 134-byte Git LFS pointer.
  • Knowing whether every audio file has a transcript, and whether that transcript is parseable.
  • Knowing whether a chunk appears twenty times because it is duplicated in source, or because the corpus has genuine repetition.
  • Knowing whether a media file is safe to train on, embed, or redistribute.

Alys treats these as first-class problems, not afterthoughts.

In this run, the source material was speech-heavy and earnings-specific. That meant validating real MP3 headers, pairing audio with .nlp transcript sidecars, chunking nearly ten million tokens with overlap, deduplicating across a 22-thousand-chunk corpus, and producing multiple export profiles for different AI workflows.

A useful mental model:

pipeline
input01

raw checkout

stage02

real media validation

stage03

transcript pairing

stage04

document parsing

stage05

chunking

stage06

deduplication

stage07

readiness scoring

stage08

workflow-specific exports

Every arrow is a place where a weaker pipeline can silently lose quality.

A glossary of what the metrics actually mean

It is easy to glance at a dashboard and nod. It is harder to know what each number implies for the dataset sitting in S3. Here is the vocabulary this run uses.

Dataset A structured collection of examples, documents, media, metadata, and labels. A folder full of files is not a dataset. A dataset has shape, provenance, and quality signals that tell you whether it is safe to use.

Document A parsed file that the pipeline can reason about. In this run, 990 files were indexed and 801 became parsed documents. The 189 that did not count as documents were mostly media files and sidecar metadata.

Token The unit of consumption for transformer models. A token is smaller than a word sometimes and larger than a character usually. 9,662,746 tokens is the real scale of what the pipeline processed, not a count of words or pages.

Chunk A bounded slice of a document. Chunks are what make long corpora usable for retrieval, embedding, and training. Without chunking, you feed a model entire earnings transcripts and hope the context window survives.

Canonical chunk A chunk that made it through filtering and deduplication. 22,306 were created; 20,396 were accepted. The 1,910 rejected chunks were duplicates, too short, too long, or otherwise unsuitable.

Provenance The source trail attached to every output row: file path, content hash, transcript pairing, chunk identity, and other evidence that tells you exactly where a record came from. Provenance is what saves you when a downstream user asks "why did the model say this?"

Sidecar A companion file placed next to another file. A transcript sidecar makes an MP3 searchable. A metadata sidecar declares license, language, owner, consent status, and usage restrictions.

Git LFS pointer A tiny placeholder file used by Git Large File Storage. It looks like a file in your checkout, but it is not the real asset. Feeding pointers into an audio parser produces silent failures that are infuriating to debug.

What had to be fixed before the pipeline could even start

The first phase was not AI. It was basic dataset hygiene.

Materializing real media from a Git checkout

The source repository used Git LFS for audio storage. After a standard git clone, the working tree contained pointers, not MP3s. Alys ran a validation pass that identified every pointer file and materialized it into real bytes.

Directory

Directory

earnings21/media

01

Result

44 MP3s materialized

Directory

earnings22/media

02

Result

125 MP3s materialized

Directory

earnings22/subset10/media

03

Result

10 symlinks pointing into earnings22/media

After materialization, zero Git LFS pointers remained. The audio files had valid MP3 headers. This is the step that prevents the silent corruption where your "audio dataset" is actually 189 text files containing hashes.

Pairing transcripts to audio

Audio without transcripts is an opaque signal. You cannot chunk it, cannot retrieve from it, and cannot evaluate a speech model on it. Alys added transcript sidecar symlinks so that each MP3 could connect to the existing .nlp transcript that described its content.

The run added 179 sidecar symlinks. By the end, transcript coverage hit 100%: every detected audio file had an associated transcript sidecar.

The pairing is loose by design. Alys does not require transcripts to live in the same directory. It uses a resolution pass that tries same-name matching, directory-relative matching, and index-based association. This matters because real-world datasets are rarely as tidy as tutorials pretend.

The pipeline: seven stages

Stage 1. Materialize the checkout

Real bytes first, everything else later. The validation pass confirmed that every media file was present, readable, and had a valid header. If a file failed this stage, it was quarantined before it could poison the rest of the pipeline.

Stage 2. Pair media with transcripts

Alys built a bidirectional lookup between audio files and transcript sidecars. A media file without a transcript is not an error, but it is flagged as incomplete. In this run, zero audio files were orphaned.

Stage 3. Parse files into documents

990 files were indexed. 801 became parsed documents containing extractable text. The remaining 189 were media files and metadata sidecars that do not parse into document content.

This is where encoding issues, malformed XML, and corrupted text files surface. Alys logs which files parsed and which did not, so you can inspect the failures instead of discovering them downstream.

Stage 4. Chunk the corpus

9,662,746 tokens were split into 22,306 chunks using bounded chunking with configurable overlap. Overlap is not a luxury. Without it, a sentence that spans a chunk boundary gets bisected, and retrieval systems return half a thought.

The chunk sizing in this run was tuned for RAG workflows: large enough to preserve context, small enough to keep embedding costs reasonable.

Stage 5. Dedupe and accept canonical chunks

22,306 chunks were reduced to 20,396 canonical chunks. The deduplication pass removes near-duplicate and exact-duplicate chunks based on normalized content hashes.

Why does this matter? If the same boilerplate legal disclaimer appears in fifty earnings transcripts, and you do not deduplicate, your retrieval system will overrepresent that disclaimer and underweight the actual financial content. In training data, duplicates create hidden overfitting.

Stage 6. Score readiness

Alys evaluates every dataset on six dimensions:

  • Knowledge quality: General signal that the corpus is structured and useful.
  • Fine-tuning suitability: Whether the shape of the text exports supports instruction tuning.
  • RAG suitability: Whether the chunks are shaped well for retrieval.
  • Eval suitability: Whether the corpus can support testable QA and assertion records.
  • Grounding: Whether outputs have enough source attachment for citation and review.
  • Structure: Whether formatting is consistent enough for stable generation.
  • Diversity: Whether accepted chunks cover a broad range of semantic groups.
  • AI readiness benchmark: Composite score after cleanup, accounting for duplication, retrieval separation, grounding density, and format consistency.

Scores are not decoration. They are hypotheses that the export phase tests. If RAG suitability is low, the rag-chunks.jsonl export will be smaller or flagged.

Stage 7. Export multiple dataset profiles

One export shape cannot serve every workflow. Alys writes separate artifacts for different downstream uses.

pipeline
input01

accepted canonical chunks

stage02

fine-tuning records

stage03

RAG chunks

stage04

QA records

stage05

eval records

stage06

embedding corpus

stage07

media manifest

stage08

debug reports

stage09

redaction review

The export artifacts: what each file is for

File

File

openai-finetune.jsonl

01

Purpose

OpenAI-style instruction records

Shape

{"messages": [...]}

File

anthropic-instruction.jsonl

02

Purpose

Anthropic-style instruction records

Shape

{"instruction": ..., "response": ...}

File

rag-chunks.jsonl

03

Purpose

Retrieval chunks with metadata

Shape

chunk + provenance + source hash

File

qa-dataset.jsonl

04

Purpose

Question-answer records for inspection

Shape

{"question": ..., "answer": ..., "source": ...}

File

eval-dataset.jsonl

05

Purpose

Evaluation records for testing

Shape

assertions, expected answers, or benchmarks

File

embeddings-corpus.jsonl

06

Purpose

Text records for vector search

Shape

clean text + id, no instruction wrapping

File

media-manifest.json

07

Purpose

Audio inventory

Shape

file list, transcript pairings, hashes, statuses

File

media-dataset-card.json

08

Purpose

Governance summary

Shape

license status, language, owner, restrictions

File

media-debug-report.json

09

Purpose

Machine-readable diagnostics

Shape

warnings, file-level issues, recommendations

File

media-redaction-review.jsonl

10

Purpose

Rows requiring human review

Shape

flagged content with source pointers

The total record count across primary exports: 122,376.

Each record carries provenance back to its source document, its chunk index, and its media pairing (if applicable). This is what separates a dataset from a pile of strings.

Scoring in depth: what the numbers actually measure

Dimension

Dimension

Knowledge quality

01

Score

80/100

What it measures

The accepted corpus has real content density. Not too much boilerplate, not too fragmented.

Dimension

Fine-tuning suitability

02

Score

81/100

What it measures

Text exports are viable for instruction tuning, but media governance is incomplete. This score is gated by the media readiness floor.

Dimension

RAG suitability

03

Score

82/100

What it measures

Chunks have enough context, overlap, and metadata to support retrieval.

Dimension

Eval suitability

04

Score

81/100

What it measures

Corpus supports question-answer and assertion generation for benchmarking.

Dimension

Grounding

05

Score

88/100

What it measures

Most outputs carry source paths and hashes. A downstream system can say "this came from Q3_2022_AAPL.nlp, chunk 17."

Dimension

Structure

06

Score

83/100

What it measures

Formatting is consistent enough that chunk boundaries land on semantic breaks more often than mid-sentence.

Dimension

Diversity

07

Score

100/100

What it measures

The accepted chunks cover a broad range of topics and speakers across the earnings corpus.

Dimension

AI readiness benchmark

08

Score

98/100

What it measures

After cleanup, duplication is low, retrieval separation is clean, grounding is dense, and formats are consistent.

The fine-tuning suitability score of 81 is clipped by media governance. Even if the text is perfect, you should not train on audio without knowing who owns it and whether you have consent.

The 431 warnings: why zero critical errors is not zero problems

A critical diagnostic means something blocks basic use: missing real media, broken pairings, corrupted files. This run had zero critical diagnostics. Good.

But it had 431 warnings across 189 media files. Warnings do not stop the pipeline. They tell you the dataset is not yet clean enough to publish, redistribute, or use as training infrastructure without review.

Missing media metadata sidecars

There were no same-name .metadata.json files alongside the audio. That means the dataset declares nothing about:

  • License (CC-BY, proprietary, unknown)
  • Source (company IR page, third-party aggregator, internal recording)
  • Owner (who recorded the call, who owns the copyright)
  • Language (English, with code-switching, or entirely another language)
  • Consent status (was this call intended for public redistribution)
  • Restrictions (no-training clauses, embargo dates, geographic limits)

Without this, any ML team downstream has to rediscover governance manually. That is not sustainable at scale.

Untimestamped transcripts

The transcripts were plain text, not VTT or SRT. This means retrieval can cite a source file, but not an exact audio interval. If you ask a speech model "what did the CFO say at minute 14?", the chunk metadata can only narrow it to a transcript, not a timestamp.

Timestamps also matter for training data alignment. If you want to supervise a speech-to-text model with chunked transcripts, you need start and end times.

Unavailable ffprobe

Alys could not inspect duration, codec, bitrate, or stream layout because ffprobe was not installed on the runner. The MP3 headers were valid, so the files were not rejected. But the debug report is missing depth: you do not know whether a file is 128 kbps or 320 kbps, mono or stereo, truncated or complete.

Install ffmpeg before the next run. It is a one-line fix that turns 431 shallow warnings into 431 specific facts.

Redaction findings

Alys flagged sensitive transcript content for human review. This is not a false-positive spam filter. It is a deliberate checkpoint. Earnings calls contain:

  • Names and titles of executives and analysts
  • Forward-looking statements that may be material
  • Revenue figures, guidance ranges, and strategic plans
  • Occasionally, personally identifiable information from Q&A

Before training or redistributing, a human should walk through media-redaction-review.jsonl and suppress or anonymize direct identifiers.

What is ready now (and what is not)

Workflow

Workflow

RAG

01

Ready?

yes

Reason

Text and chunk exports are strong. Grounding scores are high.

Workflow

Embeddings

02

Ready?

yes

Reason

Accepted chunks are clean and citation-ready.

Workflow

Evaluations

03

Ready?

yes

Reason

Corpus supports QA and assertion generation.

Workflow

Fine-tuning (text only)

04

Ready?

yes

Reason

Instruction exports are structurally sound.

Workflow

Fine-tuning (media)

05

Ready?

no

Reason

Rights metadata is absent and redaction is unreviewed.

Workflow

Redistribution

06

Ready?

no

Reason

License and owner fields are empty. Do not publish until populated.

Workflow

Production speech training

07

Ready?

no

Reason

Timestamps are missing; ffprobe metadata is unavailable.

What the next run should fix

  1. Add metadata sidecars. Create a .metadata.json next to every MP3 with license, source, owner, language, consent_status, and restrictions.
  2. Review redaction findings. Open media-redaction-review.jsonl, inspect each flagged row, and suppress or anonymize direct identifiers.
  3. Convert transcripts to timed captions. Plain text is fine for RAG. For speech training and interval-level retrieval, convert transcripts to VTT or SRT so chunks can cite exact audio start and end times.
  4. Install ffmpeg/ffprobe. This is the cheapest win: it turns shallow media warnings into precise codec and duration diagnostics.

These are not aesthetic improvements. They are the difference between a prototype dataset and infrastructure you can hand to another team with confidence.

Edge cases worth noting

Symlink handling. The subset10 directory contained symlinks into earnings22/media. Alys followed symlinks and treated them as valid media pairings, not as duplicate files. This matters when you are working with dataset subsets or views that reuse a shared media pool.

Git LFS pointer resilience. Alys does not just check file extensions. It reads the first few bytes of every candidate media file. A real MP3 starts with an MPEG frame sync pattern; a Git LFS pointer starts with version https://git-lfs.github.com/spec/. This has saved hours more than once.

Chunk boundary semantics. Overlap is configured per-run, but its default is tuned to preserve sentence boundaries. In practice, this means chunks do not always have identical byte lengths. Some are slightly shorter or longer to avoid splitting after a clause introducer like "However," or "Looking forward."

Deduplication at 10M tokens. At 9.66M tokens and 22,306 chunks, deduplication is not a simple string equality check. Alys normalizes whitespace, lowercases, and removes common boilerplate before hashing. This is why the diversity score hit 100: the remaining 20,396 chunks genuinely cover distinct content.

Why this run matters

Earnings calls are a specific, high-value domain for AI research and products. They contain real, spontaneous, domain-dense speech. But the path from "downloaded some IR recordings" to "usable ML dataset" is longer than most logs admit.

This run shows what honest dataset preparation looks like: fixing the checkout first, pairing everything second, chunking and deduplication third, and refusing to call a dataset "done" just because JSONL files were written.

The 431 warnings are the most important part of the export. They say: the pipeline worked, but governance is incomplete. The media-redaction-review.jsonl exists because redaction should not be an afterthought. The missing .metadata.json files exist as a checklist.

Good data infrastructure does not only celebrate what succeeded. It maintains a precise, auditable list of what still needs fixing before the dataset influences a model or a retrieval system.

Final state

snippet
prepared/56b9a700be3d

primary exports: ready
RAG:              yes
embeddings:       yes
evals:            yes
media training:   needs review
critical diagnostics: 0
warning diagnostics:  431

The dataset is a solid foundation. Use it for retrieval, embeddings, and evaluation. Fix the four items in the Next Run checklist before you train on it, publish it, or ship it to production.