Self-hosted Lecture-to-Quiz: Local LLM MCQ Generation with Deterministic Quality Control
Organizations: Department of Biomedical Science, College of Life and Health Sciences, Chubu University; Center for AI, Mathematical and Data Sciences, Chubu University; Kasugai, Aichi 487-8501, Japan
Abstract
We present an end-to-end self-hosted (API-free) pipeline, where API-free means that lecture content is not sent to any external LLM service, that converts lecture PDFs into multiple-choice questions (MCQs) using a local LLM plus deterministic quality control (QC). The pipeline is designed for black-box minimization: LLMs may assist drafting, but the final released artifacts are plain-text question banks with an explicit QC trace and without any need to call an LLM at deployment time. We run a seed sweep on three short "dummy lectures" (information theory, thermodynamics, and statistical mechanics), collecting 15 runs x 8 questions = 120 accepted candidates (122 attempts total under bounded retries). All 120 accepted candidates satisfy hard QC checks (JSON schema conformance, a single marked correct option, and numeric/constant equivalence tests); however, the warning layer flags 8/120 items (spanning 8 runs) that expose residual quality risks such as duplicated distractors or missing rounding instructions. We report a warning taxonomy with concrete before->after fixes, and we release the final 24-question set (three lectures x 8 questions) as JSONL/CSV for Google Forms import (e.g., via Apps Script or API tooling) included as ancillary files under anc/. Finally, we position the work through the AI to Learn (AI2L) rubric lens and argue that self-hosted MCQ generation with explicit QC supports privacy, accountability, and Green AI in educational workflows.
Figures & tables
| Component | Setting |
|---|---|
| Execution | Google Colab Pro+ (NVIDIA A100) |
| Model | Qwen2.5-14B-Instruct (GGUF, Q4_K_M) via llama-cli [ 12 , 13 , 14 , 11 ] |
| Context window | 4096 |
| Decoding | temperature 0.2, top_p 0.9, max_new_tokens 900 |
| Seeds | {0,1,2,3,4} (seed sweep; recorded per run) |
| Retry budget | retry_max = 3 per question |
| Metric | Value | Notes |
|---|---|---|
| Runs | 15 | 3 lectures 5 seeds |
| Target items | 120 | 8 per run |
| QC acceptance | 120/120 | Acceptance rate 1.0 |
| Total attempts | 122 | Includes retries |
| Retry rate | 1.6% | 2/122 attempts (1.7% overhead per item) |
| Runtime / run | 58.55 2.34 s | Min 55.29, max 63.50 |
| Lecture | Seed | Runtime (s) | s/q | Tries | Retries | Retry (%) | Flags |
|---|---|---|---|---|---|---|---|
| InfoTheory | 0 | 57.22 | 7.15 | 8 | 0 | 0.0 | Dup |
| InfoTheory | 1 | 57.02 | 7.13 | 8 | 0 | 0.0 | Rnd |
| InfoTheory | 2 | 57.81 | 7.23 | 8 | 0 | 0.0 | – |
| InfoTheory | 3 | 56.86 | 7.11 | 8 | 0 | 0.0 | – |
| InfoTheory | 4 | 63.50 | 7.94 | 9 | 1 | 11.1 | – |
| Thermodynamics | 0 | 58.84 | 7.35 | 8 | 0 | 0.0 | – |
| Flag | Count | Share | Typical cause and mitigation |
|---|---|---|---|
| Rnd | 7 | 5.8% | Numeric approximation without explicit rounding instruction; mitigate by adding “approximately” or specifying rounding digits in the stem/template. |
| Dup | 1 | 0.8% | Two distractors evaluate to the same constant; mitigate via equivalence checks + re-generation or by constraining distractor generation. |
| Warning type | Before (flagged excerpt) | After (minimal fix) |
|---|---|---|
| duplicate_options_numeric_const | L01_Q01 (seed 0) included two options that evaluate to the same constant: C and E . | Replace one distractor with a non-equivalent expression (e.g., E ) so that all five options are distinct. |
| rounding_instruction_missing_suspect | L01_Q02 (seed 1) asked for for and offered a decimal correct option (0.881 bits) without an explicit rounding rule. | Add a rounding contract in the stem (e.g., “Round to three decimal places”) or redesign the item to ask for the symbolic expression . |
| Set | Def./formula | Property/law | Worked ex. | Mean stem (words) | Mean expl. (words) |
|---|---|---|---|---|---|
| L01 | 2 | 5 | 1 | 18.4 | 37.8 |
| L02 | 4 | 4 | 0 | 22.5 | 48.4 |
| L03 | 5 | 3 | 0 | 28.4 | 43.2 |
| Overall | 11 | 12 | 1 | 23.1 | 43.1 |
| Run | Item | Warning | Why it was flagged / how it is handled |
|---|---|---|---|
| L01 (seed 0) | Q01 | duplicate_options_numeric_const | Two distractors were constant-equivalent: log2(0.25) and 2*log2(0.5) both evaluate to . We resolve this either by regenerating a single distractor or by selecting another seed run without the duplication. |
| L01 (seed 1) | Q02 | rounding_instruction_missing_suspect | The keyed answer was reported as 0.881 bits but the stem did not specify whether rounding (and to how many digits) was required. A minimal fix is to add “approximately” or an explicit rounding rule. |
| L02 (seed 1) | Q06 | rounding_instruction_missing_suspect | A conservative heuristic was triggered by a comparison to a numerical constant (“ ”) despite the item being qualitative. This illustrates why the warnings are best interpreted as a review queue , not as automatic rejection. |
| AI2L pillar | Local inference | QC + rubric | Static export | Remaining gap |
|---|---|---|---|---|
| Transparency (black-box exclusion) | ✓ | ✓ | ✓ | Drafting model remains opaque |
| Accountability (human verification) | — | ✓ | ✓ | Human final approval still required |
| Privacy (info protection) | ✓ | ✓ | ✓ | Depends on local material handling |
| Green AI (sustainability) | ✓ | — | ✓ | Authoring still compute-heavy |
Appendix figures & tables2 assets
Supplementary material from the paper’s appendix.
Appendix
| Field | Description |
|---|---|
| ID | Unique ID within the run (e.g., Q01 ). |
| SourcePages | Page range supporting the item (traceability). |
| Question | MCQ stem. |
| OptionA – OptionE | Five answer choices. |
| CorrectOption | Correct choice letter (A–E). |
| Explanation | Short rationale grounded in the excerpt. |
| Field | Description |
|---|---|
| lecture | Lecture identifier (e.g., Lecture01 ). |
| run | Selected run tag (e.g., RUN4 ). |
| seed | RNG seed for the run. |
| pdf_basename | Input PDF filename (basename). |
| source_pages | Page pointer supporting the item. |
| id | Stable item ID (e.g., L01_Q01 ). |