drodel01/thesis-repository

Code for my Master's thesis

Python

0

1 commits

updated Mar 5, 2026

See the code

README

Master's Thesis — Code

The framework measures how novel LLM-generated text is relative to pretraining data, using a three-stage pipeline: dense retrieval (FAISS + GIST embeddings), late-interaction reranking (ColBERTv2), and human baseline calibration.

Models studied: SmolLM and SmolLM2 (360M and 1.7B parameters, base and instruct variants).

Repository Structure

thesis-repository/
│
├── download_data_code/                  Download pretraining corpora + benchmarks
├── dolma/                               HuggingFace dataset loader for Dolma
├── calc_chunks_and_embeddings_code/     Chunk corpora + compute GIST embeddings
├── create_FAISS_index_SmolLM.py/.sbatch Build FAISS HNSW index (SmolLM corpora)
├── create_FAISS_index_SmolLM2.py/.sbatch Build FAISS HNSW index (SmolLM2 corpora)
├── analyze_generations_novelty_code/    Core novelty analysis pipeline
├── effect_of_chunking_borders/          Chunking border analysis experiment
├── eval_benchmarks/                     Model evaluation (lm-eval-harness + custom)
├── eval_benchmarks_lighteval/           GSM8K evaluation (lighteval)
├── results/generation_novelty/          Plotting + statistical analysis
├── sum_cpu_time.py                      Computational cost (Appendix A.5)
├── container.def                        Singularity/Apptainer container definition
└── requirements.txt                     Python dependencies

Pipeline Overview

The full pipeline runs on an HPC cluster using SLURM and Singularity containers. Each stage has Python scripts and corresponding .sbatch job files.

Stage 1: Data Download

download_data_code/ — Download pretraining corpora and benchmark datasets.

ScriptDescription
download_DCLM_dedup.pyDCLM corpus
download_cosmopediav2.pyCosmopedia v2
download_finemath.pyFineMath + InfiWebMath
download_fineweb_edu_dedup.pyFineWeb-edu
download_python_edu.pyPython-edu (from Software Heritage S3)
download_stack_edu.pyStack-edu (from Software Heritage S3)
download_dolma.sh, download_dolma_second_step.pyDolma human baseline
download_instruct.pyInstruct-tuning data
download_benchmarks_for_perplexity.pyBenchmark datasets
concat_stack_edu_Java_parts.pyPost-processing: concatenate Stack-edu Java parts

dolma/dolma.py — HuggingFace dataset loader for Dolma.

Stage 2: Chunking + Embeddings

calc_chunks_and_embeddings_code/ — Split corpora into fixed-size token windows and compute GIST-large embeddings.

Script patternDescription
calculate_chunks_*.pyChunk each dataset into token windows
calculate_embeddings_*.pyCompute GIST-large embeddings (GPU)
utils.pyShared text assembly utilities

Datasets chunked: Cosmopedia v2, DCLM, FineMath, FineWeb-edu, InfiWebMath, Python-edu, Stack-edu, GSM8K, OpenRewrite, TruthfulQA, instruct data, OpenHermes-2.5.

Stage 3: FAISS Index Construction

ScriptDescription
create_FAISS_index_SmolLM.pyBuild FAISS HNSW index from SmolLM corpus embeddings
create_FAISS_index_SmolLM2.pyBuild FAISS HNSW index from SmolLM2 corpus embeddings

Stage 4: Novelty Analysis

analyze_generations_novelty_code/ — Core novelty analysis pipeline.

Script patternDescription
analyze_generations_*.pyStage 1: FAISS retrieval for model generations (Dolma, GSM8K, TruthfulQA, OpenRewrite)
rerank_top_100_with_granularity*.pyStage 2: ColBERTv2 reranking at multiple chunk granularities
combine_*.pyCombine batched SmolLM2 results
analyze_ngram_vs_embed_toy_examples.pyToy examples for Figure 1.1
analyze_ngram_vs_embed_toy_examples_post_hoc.pyPost-hoc toy example analysis
build_compare_novelty_with_human_intuition.pyHuman intuition comparison (Appendix A.6)
get_token_lengths_*.pyToken length computation for normalization
sum_faiss_times.pyFAISS timing aggregation
utils.pyFAISS search, normalization, shared utilities

Stage 5: Model Evaluation

eval_benchmarks/ — Model evaluation using lm-eval-harness and custom evaluations.

ScriptDescription
custom_eval_openrewrite_lm.pyCustom OpenRewriteEval evaluation
SmolLM1/*.sbatchSmolLM1 evaluation jobs (lm-eval + OpenRewrite)
SmolLM2/*.sbatchSmolLM2 evaluation jobs (lm-eval + OpenRewrite)

eval_benchmarks_lighteval/ — GSM8K evaluation using lighteval.

ScriptDescription
tasks.pyCustom task definitions
math_utils.pyMath answer parsing
SmolLM1/*.sbatch, SmolLM2/*.sbatchGSM8K evaluation jobs per model
test_lighteval.sbatchTest job

Stage 6: Chunking Border Experiment

effect_of_chunking_borders/ — Analyzes how chunking borders affect retrieval results (Figure A.2).

ScriptDescription
find_texts_for_analysis.pyFind test documents
prepare_chunks.pyPrepare shifted-border chunks
prepare_chunks_test.pyUnit test for chunking logic
analyze_similarity.pyCompute similarity across borders
plot_ranking.pyProduce Figure A.2

Stage 7: Plotting + Statistical Analysis

results/generation_novelty/ — All plotting and statistical testing scripts.

ScriptProduces
create_simple_novelty_graph_relative_to_human.pyFigure 4.1 — Novelty profiles on Dolma
create_simple_novelty_graph_relative_to_human_gen_benchmark.pyFigure 4.2 — Novelty profiles on domain-specific benchmarks
create_simple_novelty_graph_relative_to_human_violin_plots.pyFigure A.3 — Violin plots (Dolma)
create_simple_novelty_graph_relative_to_human_violin_plots_gen_benchmark.pyFigure A.4 — Violin plots (per-domain)
create_simple_novelty_graph_relative_to_human_filter_incoherent.pyFigure A.5 — Coherence filtering
create_simple_novelty_graph_relative_to_human_alt_answer.pyFigure A.6 — Alternative TruthfulQA answers
reranking_ablation.pyFigure A.1 — FAISS-to-ColBERT reranking histogram
calculate_wilcoxon_tests.pyTables A.1–A.10 (benchmark p-values)
calculate_wilcoxon_tests_dolma.pyTables A.1–A.10 (Dolma p-values)
calculate_wilcoxon_tests_dolma_context_comparison.pyTables A.9–A.10 (prompted vs unprompted)
generate_wilcoxon_tables.pyFormat LaTeX p-value tables
get_qualitative_examples_truthfulqa.pyQualitative examples (Section 4.3)
get_qualitative_examples_gsm8k.pyQualitative examples (Section 4.3)
utils.pyShared plotting and data loading utilities

Miscellaneous

FileDescription
sum_cpu_time.pyComputational cost calculation (Appendix A.5)
results/times.ttfFont file used for plots

Infrastructure

Container

The Singularity/Apptainer container is defined in container.def:

  • Base image: Ubuntu 24.04
  • Python 3.11 (via uv)
  • PyTorch with CUDA 12.8
  • All dependencies from requirements.txt

Build with:

apptainer build container.sif container.def

Running Jobs

All scripts are designed to run inside the container via SLURM. The general pattern:

singularity run \
    --bind $(pwd):/mnt \
    --bind $HF_HOME:/hf-cache \
    container.sif \
    bash -c "export HF_HOME=/hf-cache && python3 /mnt/script.py --job-num $SLURM_ARRAY_TASK_ID"

Data Paths

All scripts run inside a Singularity container with bind mounts:

Host pathContainer pathContents
data//mnt/data/Pretraining corpora, benchmark datasets
data/smollm2_corpus//mnt/data/smollm2_corpus/SmolLM2-specific chunked data
data/FAISS//mnt/data/FAISS/FAISS indices (SmolLM)
data/smollm2_corpus/FAISS//mnt/data/smollm2_corpus/FAISS/FAISS indices (SmolLM2)
results//mnt/results/Novelty analysis results, plots
$HF_HOME/hf-cacheHuggingFace model/dataset cache

Environment Variables

VariablePurpose
HF_TOKENHuggingFace Hub API token (for uploads)
HF_HOMEHuggingFace cache directory
SENTRY_DSNSentry error tracking DSN (optional)
WANDB_API_KEYWeights & Biases API key (for eval benchmarks)

Key Dependencies

  • FAISS (faiss-cpu): Dense retrieval with HNSW indices
  • sentence-transformers: GIST-large embedding model
  • pylate / ragatouille: ColBERTv2 reranking
  • datasets / huggingface-hub: Data loading and publishing
  • spacy (en_core_web_sm, en_core_web_trf): Text processing
  • scipy: Wilcoxon rank-sum tests
  • matplotlib / pandas / numpy: Plotting and analysis
  • sentry-sdk: Error tracking (optional)
  • boto3: S3 access for Software Heritage downloads

Thesis Figure/Table → Script Mapping

Figure/TableScript
Figure 1.1(a)Hand-designed, based on analyze_generations_novelty_code/analyze_ngram_vs_embed_toy_examples.py
Figure 1.1(b)analyze_generations_novelty_code/analyze_ngram_vs_embed_toy_examples.py
Algorithm 1Pseudocode in LaTeX (no script)
Figure 4.1results/generation_novelty/create_simple_novelty_graph_relative_to_human.py
Figure 4.2results/generation_novelty/create_simple_novelty_graph_relative_to_human_gen_benchmark.py
Table 4.1Inline LaTeX table (no script)
Figure A.1results/generation_novelty/reranking_ablation.py
Figure A.2effect_of_chunking_borders/plot_ranking.py
Figure A.3results/generation_novelty/create_simple_novelty_graph_relative_to_human_violin_plots.py
Figure A.4results/generation_novelty/create_simple_novelty_graph_relative_to_human_violin_plots_gen_benchmark.py
Figure A.5results/generation_novelty/create_simple_novelty_graph_relative_to_human_filter_incoherent.py
Figure A.6results/generation_novelty/create_simple_novelty_graph_relative_to_human_alt_answer.py
Tables A.1–A.10results/generation_novelty/calculate_wilcoxon_tests*.py, generate_wilcoxon_tables.py

drodel01/thesis-repository

Code for my Master's thesis

Python

0

1 commits

updated Mar 5, 2026

See the code

README

Master's Thesis — Code

The framework measures how novel LLM-generated text is relative to pretraining data, using a three-stage pipeline: dense retrieval (FAISS + GIST embeddings), late-interaction reranking (ColBERTv2), and human baseline calibration.

Models studied: SmolLM and SmolLM2 (360M and 1.7B parameters, base and instruct variants).

Repository Structure

thesis-repository/
│
├── download_data_code/                  Download pretraining corpora + benchmarks
├── dolma/                               HuggingFace dataset loader for Dolma
├── calc_chunks_and_embeddings_code/     Chunk corpora + compute GIST embeddings
├── create_FAISS_index_SmolLM.py/.sbatch Build FAISS HNSW index (SmolLM corpora)
├── create_FAISS_index_SmolLM2.py/.sbatch Build FAISS HNSW index (SmolLM2 corpora)
├── analyze_generations_novelty_code/    Core novelty analysis pipeline
├── effect_of_chunking_borders/          Chunking border analysis experiment
├── eval_benchmarks/                     Model evaluation (lm-eval-harness + custom)
├── eval_benchmarks_lighteval/           GSM8K evaluation (lighteval)
├── results/generation_novelty/          Plotting + statistical analysis
├── sum_cpu_time.py                      Computational cost (Appendix A.5)
├── container.def                        Singularity/Apptainer container definition
└── requirements.txt                     Python dependencies

Pipeline Overview

The full pipeline runs on an HPC cluster using SLURM and Singularity containers. Each stage has Python scripts and corresponding .sbatch job files.

Stage 1: Data Download

download_data_code/ — Download pretraining corpora and benchmark datasets.

ScriptDescription
download_DCLM_dedup.pyDCLM corpus
download_cosmopediav2.pyCosmopedia v2
download_finemath.pyFineMath + InfiWebMath
download_fineweb_edu_dedup.pyFineWeb-edu
download_python_edu.pyPython-edu (from Software Heritage S3)
download_stack_edu.pyStack-edu (from Software Heritage S3)
download_dolma.sh, download_dolma_second_step.pyDolma human baseline
download_instruct.pyInstruct-tuning data
download_benchmarks_for_perplexity.pyBenchmark datasets
concat_stack_edu_Java_parts.pyPost-processing: concatenate Stack-edu Java parts

dolma/dolma.py — HuggingFace dataset loader for Dolma.

Stage 2: Chunking + Embeddings

calc_chunks_and_embeddings_code/ — Split corpora into fixed-size token windows and compute GIST-large embeddings.

Script patternDescription
calculate_chunks_*.pyChunk each dataset into token windows
calculate_embeddings_*.pyCompute GIST-large embeddings (GPU)
utils.pyShared text assembly utilities

Datasets chunked: Cosmopedia v2, DCLM, FineMath, FineWeb-edu, InfiWebMath, Python-edu, Stack-edu, GSM8K, OpenRewrite, TruthfulQA, instruct data, OpenHermes-2.5.

Stage 3: FAISS Index Construction

ScriptDescription
create_FAISS_index_SmolLM.pyBuild FAISS HNSW index from SmolLM corpus embeddings
create_FAISS_index_SmolLM2.pyBuild FAISS HNSW index from SmolLM2 corpus embeddings

Stage 4: Novelty Analysis

analyze_generations_novelty_code/ — Core novelty analysis pipeline.

Script patternDescription
analyze_generations_*.pyStage 1: FAISS retrieval for model generations (Dolma, GSM8K, TruthfulQA, OpenRewrite)
rerank_top_100_with_granularity*.pyStage 2: ColBERTv2 reranking at multiple chunk granularities
combine_*.pyCombine batched SmolLM2 results
analyze_ngram_vs_embed_toy_examples.pyToy examples for Figure 1.1
analyze_ngram_vs_embed_toy_examples_post_hoc.pyPost-hoc toy example analysis
build_compare_novelty_with_human_intuition.pyHuman intuition comparison (Appendix A.6)
get_token_lengths_*.pyToken length computation for normalization
sum_faiss_times.pyFAISS timing aggregation
utils.pyFAISS search, normalization, shared utilities

Stage 5: Model Evaluation

eval_benchmarks/ — Model evaluation using lm-eval-harness and custom evaluations.

ScriptDescription
custom_eval_openrewrite_lm.pyCustom OpenRewriteEval evaluation
SmolLM1/*.sbatchSmolLM1 evaluation jobs (lm-eval + OpenRewrite)
SmolLM2/*.sbatchSmolLM2 evaluation jobs (lm-eval + OpenRewrite)

eval_benchmarks_lighteval/ — GSM8K evaluation using lighteval.

ScriptDescription
tasks.pyCustom task definitions
math_utils.pyMath answer parsing
SmolLM1/*.sbatch, SmolLM2/*.sbatchGSM8K evaluation jobs per model
test_lighteval.sbatchTest job

Stage 6: Chunking Border Experiment

effect_of_chunking_borders/ — Analyzes how chunking borders affect retrieval results (Figure A.2).

ScriptDescription
find_texts_for_analysis.pyFind test documents
prepare_chunks.pyPrepare shifted-border chunks
prepare_chunks_test.pyUnit test for chunking logic
analyze_similarity.pyCompute similarity across borders
plot_ranking.pyProduce Figure A.2

Stage 7: Plotting + Statistical Analysis

results/generation_novelty/ — All plotting and statistical testing scripts.

ScriptProduces
create_simple_novelty_graph_relative_to_human.pyFigure 4.1 — Novelty profiles on Dolma
create_simple_novelty_graph_relative_to_human_gen_benchmark.pyFigure 4.2 — Novelty profiles on domain-specific benchmarks
create_simple_novelty_graph_relative_to_human_violin_plots.pyFigure A.3 — Violin plots (Dolma)
create_simple_novelty_graph_relative_to_human_violin_plots_gen_benchmark.pyFigure A.4 — Violin plots (per-domain)
create_simple_novelty_graph_relative_to_human_filter_incoherent.pyFigure A.5 — Coherence filtering
create_simple_novelty_graph_relative_to_human_alt_answer.pyFigure A.6 — Alternative TruthfulQA answers
reranking_ablation.pyFigure A.1 — FAISS-to-ColBERT reranking histogram
calculate_wilcoxon_tests.pyTables A.1–A.10 (benchmark p-values)
calculate_wilcoxon_tests_dolma.pyTables A.1–A.10 (Dolma p-values)
calculate_wilcoxon_tests_dolma_context_comparison.pyTables A.9–A.10 (prompted vs unprompted)
generate_wilcoxon_tables.pyFormat LaTeX p-value tables
get_qualitative_examples_truthfulqa.pyQualitative examples (Section 4.3)
get_qualitative_examples_gsm8k.pyQualitative examples (Section 4.3)
utils.pyShared plotting and data loading utilities

Miscellaneous

FileDescription
sum_cpu_time.pyComputational cost calculation (Appendix A.5)
results/times.ttfFont file used for plots

Infrastructure

Container

The Singularity/Apptainer container is defined in container.def:

  • Base image: Ubuntu 24.04
  • Python 3.11 (via uv)
  • PyTorch with CUDA 12.8
  • All dependencies from requirements.txt

Build with:

apptainer build container.sif container.def

Running Jobs

All scripts are designed to run inside the container via SLURM. The general pattern:

singularity run \
    --bind $(pwd):/mnt \
    --bind $HF_HOME:/hf-cache \
    container.sif \
    bash -c "export HF_HOME=/hf-cache && python3 /mnt/script.py --job-num $SLURM_ARRAY_TASK_ID"

Data Paths

All scripts run inside a Singularity container with bind mounts:

Host pathContainer pathContents
data//mnt/data/Pretraining corpora, benchmark datasets
data/smollm2_corpus//mnt/data/smollm2_corpus/SmolLM2-specific chunked data
data/FAISS//mnt/data/FAISS/FAISS indices (SmolLM)
data/smollm2_corpus/FAISS//mnt/data/smollm2_corpus/FAISS/FAISS indices (SmolLM2)
results//mnt/results/Novelty analysis results, plots
$HF_HOME/hf-cacheHuggingFace model/dataset cache

Environment Variables

VariablePurpose
HF_TOKENHuggingFace Hub API token (for uploads)
HF_HOMEHuggingFace cache directory
SENTRY_DSNSentry error tracking DSN (optional)
WANDB_API_KEYWeights & Biases API key (for eval benchmarks)

Key Dependencies

  • FAISS (faiss-cpu): Dense retrieval with HNSW indices
  • sentence-transformers: GIST-large embedding model
  • pylate / ragatouille: ColBERTv2 reranking
  • datasets / huggingface-hub: Data loading and publishing
  • spacy (en_core_web_sm, en_core_web_trf): Text processing
  • scipy: Wilcoxon rank-sum tests
  • matplotlib / pandas / numpy: Plotting and analysis
  • sentry-sdk: Error tracking (optional)
  • boto3: S3 access for Software Heritage downloads

Thesis Figure/Table → Script Mapping

Figure/TableScript
Figure 1.1(a)Hand-designed, based on analyze_generations_novelty_code/analyze_ngram_vs_embed_toy_examples.py
Figure 1.1(b)analyze_generations_novelty_code/analyze_ngram_vs_embed_toy_examples.py
Algorithm 1Pseudocode in LaTeX (no script)
Figure 4.1results/generation_novelty/create_simple_novelty_graph_relative_to_human.py
Figure 4.2results/generation_novelty/create_simple_novelty_graph_relative_to_human_gen_benchmark.py
Table 4.1Inline LaTeX table (no script)
Figure A.1results/generation_novelty/reranking_ablation.py
Figure A.2effect_of_chunking_borders/plot_ranking.py
Figure A.3results/generation_novelty/create_simple_novelty_graph_relative_to_human_violin_plots.py
Figure A.4results/generation_novelty/create_simple_novelty_graph_relative_to_human_violin_plots_gen_benchmark.py
Figure A.5results/generation_novelty/create_simple_novelty_graph_relative_to_human_filter_incoherent.py
Figure A.6results/generation_novelty/create_simple_novelty_graph_relative_to_human_alt_answer.py
Tables A.1–A.10results/generation_novelty/calculate_wilcoxon_tests*.py, generate_wilcoxon_tables.py