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
0 Git LFS pointers remaining
Meaning
The media files were real MP3s, not placeholder text files
Result
189 audio files
Meaning
The corpus had a meaningful speech component
Result
100% transcript coverage
Meaning
Every audio file had a transcript sidecar
Result
9,662,746 tokens parsed
Meaning
The text corpus was large enough to stress real preparation behavior
Result
20,396 canonical chunks
Meaning
Deduplication produced a clean retrieval/training base
Result
122,376 primary records
Meaning
Multiple export profiles were generated from the accepted chunks
Result
77/100 media readiness
Meaning
Media can be inspected, but governance is incomplete
Result
431 warnings
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
[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:
raw checkout
real media validation
transcript pairing
document parsing
chunking
deduplication
readiness scoring
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
earnings21/media
Result
44 MP3s materialized
Directory
earnings22/media
Result
125 MP3s materialized
Directory
earnings22/subset10/media
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.
accepted canonical chunks
fine-tuning records
RAG chunks
QA records
eval records
embedding corpus
media manifest
debug reports
redaction review
The export artifacts: what each file is for
File
openai-finetune.jsonl
Purpose
OpenAI-style instruction records
Shape
{"messages": [...]}
File
anthropic-instruction.jsonl
Purpose
Anthropic-style instruction records
Shape
{"instruction": ..., "response": ...}
File
rag-chunks.jsonl
Purpose
Retrieval chunks with metadata
Shape
chunk + provenance + source hash
File
qa-dataset.jsonl
Purpose
Question-answer records for inspection
Shape
{"question": ..., "answer": ..., "source": ...}
File
eval-dataset.jsonl
Purpose
Evaluation records for testing
Shape
assertions, expected answers, or benchmarks
File
embeddings-corpus.jsonl
Purpose
Text records for vector search
Shape
clean text + id, no instruction wrapping
File
media-manifest.json
Purpose
Audio inventory
Shape
file list, transcript pairings, hashes, statuses
File
media-dataset-card.json
Purpose
Governance summary
Shape
license status, language, owner, restrictions
File
media-debug-report.json
Purpose
Machine-readable diagnostics
Shape
warnings, file-level issues, recommendations
File
media-redaction-review.jsonl
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
Knowledge quality
Score
80/100
What it measures
The accepted corpus has real content density. Not too much boilerplate, not too fragmented.
Dimension
Fine-tuning suitability
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
Score
82/100
What it measures
Chunks have enough context, overlap, and metadata to support retrieval.
Dimension
Eval suitability
Score
81/100
What it measures
Corpus supports question-answer and assertion generation for benchmarking.
Dimension
Grounding
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
Score
83/100
What it measures
Formatting is consistent enough that chunk boundaries land on semantic breaks more often than mid-sentence.
Dimension
Diversity
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
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
RAG
Ready?
yes
Reason
Text and chunk exports are strong. Grounding scores are high.
Workflow
Embeddings
Ready?
yes
Reason
Accepted chunks are clean and citation-ready.
Workflow
Evaluations
Ready?
yes
Reason
Corpus supports QA and assertion generation.
Workflow
Fine-tuning (text only)
Ready?
yes
Reason
Instruction exports are structurally sound.
Workflow
Fine-tuning (media)
Ready?
no
Reason
Rights metadata is absent and redaction is unreviewed.
Workflow
Redistribution
Ready?
no
Reason
License and owner fields are empty. Do not publish until populated.
Workflow
Production speech training
Ready?
no
Reason
Timestamps are missing; ffprobe metadata is unavailable.
What the next run should fix
- Add metadata sidecars. Create a
.metadata.jsonnext to every MP3 withlicense,source,owner,language,consent_status, andrestrictions. - Review redaction findings. Open
media-redaction-review.jsonl, inspect each flagged row, and suppress or anonymize direct identifiers. - 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.
- 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
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.