amanyelfiky commited on
Commit
c29c4d4
·
verified ·
1 Parent(s): a4a3603

Update src/summarization/README.md

Browse files
Files changed (1) hide show
  1. src/summarization/README.md +95 -109
src/summarization/README.md CHANGED
@@ -1,116 +1,102 @@
1
- # Summarization Module 📝
2
-
3
- ## Responsibility
4
- This module handles **text summarization and conversion to structured study notes**.
5
-
6
- ## Functionality
7
- 1. Receive transcribed text from videos.
8
- 2. Use a **local mT5 model** (map-reduce pipeline) to analyze text and generate structured JSON notes.
9
- 3. Produce clean Markdown output with:
10
- - Source & Duration header
11
- - Overall Summary
12
- - Chronological Timeline (3-7 segments with Key Insight + Why It Matters)
13
- - Conclusion
14
-
15
- ## Pipeline (Map-Reduce)
16
- 1. **Map** — `TranscriptSegmenter.segment_text_by_words()` splits the transcript into
17
- fixed-size word chunks (default 350 words, safely under mT5's 512-token limit).
18
- Each chunk is summarized independently by the local model, producing one
19
- `SegmentSchema` entry per chunk.
20
- 2. **Reduce** — All chunk-level summaries are concatenated and summarized once more
21
- by the same model, producing the single overall `summary` field.
22
- 3. **Validate** The assembled result is passed through
23
- `SummarySchema.model_validate()`. If the chunk count falls outside the
24
- schema's allowed range (3-7), segments are automatically merged or padded
25
- before validation. If validation still fails, a safe schema-valid fallback
26
- is returned instead.
27
-
28
- ## Files
29
-
30
- ### 1. `schemas.py`
31
- - **Purpose:** Single source of truth for all Pydantic data models.
32
- - **Key Classes:**
33
- - `SummarySchema` — Full structured output (title, detected_language, summary, segments, suggested_category, conclusion, topics).
34
- - `SegmentSchema` — A timeline section (title, summary, key_insight, why_it_matters).
35
-
36
- ### 2. `note_generator.py`
37
- - **Purpose:** Generate notes using a local mT5 model with chunk-based map-reduce and schema validation.
38
- - **Main Class:** `NoteGenerator`
39
- - **Key Methods:**
40
- - `generateSummary(transcript, title)` — Runs the map-reduce pipeline and returns a `SummarySchema`-validated dict.
41
- - `format_notes_to_markdown(json_notes)` — Converts JSON to clean Markdown.
42
- - `format_final_notes(notes, title, url, duration)` — Wraps Markdown with Source/Duration header.
43
-
44
- ### 3. `segmenter.py`
45
- - **Purpose:** Split long texts into smaller segments for preprocessing.
46
- - **Main Class:** `TranscriptSegmenter`
47
- - **Key Methods:**
48
- - `segment_text_by_words()` — Split text into fixed-size word chunks (used by the mT5 map step).
49
- - `segment_by_time()` — Split by time intervals.
50
- - `segment_by_topic()` — Split by paragraph/topic boundaries.
51
- - `clean_text()` — Remove filler words.
52
-
53
- ## JSON Output Structure
54
- ```json
55
- {
56
- "title": "...",
57
- "detected_language": "Arabic",
58
- "summary": "Overall summary (3-5 sentences)",
59
- "segments": [
60
- {
61
- "title": "Segment title",
62
- "summary": "What this section covers",
63
- "key_insight": "Most important point",
64
- "why_it_matters": "Why this is valuable"
65
- }
66
- ],
67
- "suggested_category": "General",
68
- "conclusion": "Final takeaway",
69
- "topics": ["Topic1", "Topic2"]
70
- }
71
  ```
72
- > **Note:** `topics` and `suggested_category` are hidden metadata — not rendered in markdown, used by downstream modules only.
73
-
74
- ## Markdown Output Order
75
- 1. **Source** video URL
76
- 2. **Duration** — video length
77
- 3. **Overall Summary**one concise summary
78
- 4. **Timeline**chronological segments (3-7), each with Key Insight + Why It Matters
79
- 5. **Conclusion** final takeaway
80
-
81
- ## Labels (Localized)
82
- | Key | English | Arabic |
83
- |-----|---------|--------|
84
- | source | Source | المصدر |
85
- | duration | Duration | المدة |
86
- | summary | Overall Summary | الملخص العام |
87
- | timeline | Timeline | التسلسل الزمني |
88
- | insight | Key Insight | أهم نقطة |
89
- | why | Why It Matters | لماذا يهم؟ |
90
- | conclusion | Conclusion | الخلاصة |
91
-
92
- ## Testing
93
  ```python
94
  from src.summarization.note_generator import NoteGenerator
95
 
96
- generator = NoteGenerator()
97
- transcript = "Here is the complete video transcript..."
98
- title = "Introduction to Python"
 
 
 
 
 
 
 
 
 
 
99
 
100
- # Generate notes
101
- summary_json = generator.generateSummary(transcript, title)
102
- notes_md = generator.format_notes_to_markdown(summary_json)
103
- print(notes_md)
104
  ```
105
 
106
- ## Libraries Used
107
- - `transformers` — Load and run the local mT5 model (HuggingFace).
108
- - `sentencepiece` — Tokenizer backend required by mT5.
109
- - `langdetect` — Automatic language detection for multilingual support.
110
- - `torch` PyTorch runtime for model inference.
111
- - `pydantic` — Data validation and schema enforcement.
112
-
113
- ## Environment Variables
114
- | Variable | Default | Description |
115
- |----------|---------|-------------|
116
- | `MT5_MODEL_NAME` | `csebuetnlp/mT5_multilingual_XLSum` | HuggingFace model ID to load (fine-tuned for multilingual summarization, including Arabic) |
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Summarization Module
2
+
3
+ Part of the `Aldea-Server` project (`src/summarization`). This module turns a raw YouTube video transcript into a structured, validated set of study notes: a general summary, a chronological timeline of segments, key insights, a conclusion, and extracted topics — in either Arabic or English, auto-detected from the transcript.
4
+
5
+ ## Evolution of this module
6
+
7
+ The summarization approach went through three phases before reaching its current design:
8
+
9
+ | Phase | Approach | Outcome |
10
+ |---|---|---|
11
+ | 1 | Third-party LLM API only | Fluent output, but fully dependent on an external service (cost, latency, no offline mode) |
12
+ | 2 | Local **mT5** model | **Discontinued** output quality (coherence, accuracy) was too weak compared to the API, especially on longer/Arabic transcripts |
13
+ | 3 (current) | Hybrid: **Groq API** (Llama-3.3-70B) **or** local **Qwen2.5-0.5B-Instruct** | Best of both — high quality via the cloud path, or fully local/offline inference when data privacy or no-internet constraints apply |
14
+
15
+ Switching between the Groq and local-Qwen backends is controlled by a single `INFERENCE_MODE` flag (see `model_loader.py` in `src/utils/`, shared across the project). Both backends share the exact same prompts, chunking logic, and output schema — the rest of the app never needs to know which one produced a given summary.
16
+
17
+ > ⚠️ Evaluation note: comparisons between the three phases have been **qualitative/manual** so far (no ROUGE/BLEU scores were collected). See *Limitations* below.
18
+
19
+ ## Architecture (Map-Reduce pipeline)
20
+
21
+ ```
22
+ Transcript ─▶ TranscriptSegmenter ─▶ MAP (summarize each chunk)
23
+
24
+
25
+ REDUCE (combine into one summary)
26
+
27
+
28
+ Validate against SummarySchema (Pydantic)
29
+
30
+
31
+ Markdown formatting (timeline + conclusion)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  ```
33
+
34
+ ## Files in this module
35
+
36
+ | File | Responsibility |
37
+ |---|---|
38
+ | `note_generator.py` | `NoteGenerator`orchestrates the Map-Reduce pipeline, language detection, schema validation, fallback handling, Markdown formatting, and the "chat with this note" Q&A feature |
39
+ | `segmenter.py` | `TranscriptSegmenter` splits transcripts into chunks (by word count, by time, or by topic heuristic) and cleans filler words |
40
+ | `schemas.py` | Pydantic models (`SummarySchema`, `SegmentSchema`) that define and enforce the output contract |
41
+ | `__init__.py` | Module entry point |
42
+
43
+ > `model_loader.py` (which exposes `generate_text`, `INFERENCE_MODE`, `get_groq_client`, `_generate_text_local`) lives in `src/utils/` since it's shared by other parts of the server, not just summarization.
44
+
45
+ ## Usage
46
+
 
 
 
 
 
 
 
47
  ```python
48
  from src.summarization.note_generator import NoteGenerator
49
 
50
+ generator = NoteGenerator(chunk_size_words=200)
51
+
52
+ result = generator.generateSummary(transcript_text, video_title)
53
+ # result is a dict validated against SummarySchema
54
+
55
+ markdown_body = generator.format_notes_to_markdown(result)
56
+ final_note = generator.format_final_notes(
57
+ markdown_body,
58
+ video_title=video_title,
59
+ video_url=video_url,
60
+ duration=duration_seconds,
61
+ detected_language=result["detected_language"],
62
+ )
63
 
64
+ # Optional: ask a follow-up question grounded in the generated note
65
+ answer = generator.chat_with_note(final_note, "What's the main takeaway?")
 
 
66
  ```
67
 
68
+ ## Output schema
69
+
70
+ **`SummarySchema`**
71
+
72
+ | Field | Type | Notes |
73
+ |---|---|---|
74
+ | `title` | `str \| None` | Carried through for formatting |
75
+ | `detected_language` | `str \| None` | `"Arabic"` or `"English"` |
76
+ | `summary` | `str` | 3–5 sentence overview |
77
+ | `segments` | `list[SegmentSchema]` | 3–7 chronological sections |
78
+ | `suggested_category` | `str` | 1–2 word category, always English |
79
+ | `conclusion` | `str \| None` | Closing takeaway |
80
+ | `topics` | `list[str]` | Extracted topics (min 1) |
81
+
82
+ **`SegmentSchema`**: `title`, `summary`, `key_insight`, `why_it_matters`
83
+
84
+ ## Configuration
85
+
86
+ - **`INFERENCE_MODE`** — `"groq"` to use the Groq Cloud API (Llama-3.3-70B-Versatile), anything else to use the local Qwen2.5-0.5B-Instruct path.
87
+ - **`chunk_size_words`** (`NoteGenerator.__init__`) — default `200`. Controls how many words go into each Map-step chunk.
88
+ - Requires a valid Groq API key/credentials when `INFERENCE_MODE = "groq"` (handled by `get_groq_client()` in `model_loader.py`).
89
+ - `langdetect` is optional — if not installed, language detection falls back to an Arabic-character-ratio heuristic.
90
+
91
+ ## Limitations
92
+
93
+ - No quantitative benchmark (ROUGE/BLEU) exists yet across the API / mT5 / Qwen phases — decisions so far were based on manual review.
94
+ - The local Qwen2.5-0.5B-Instruct model is small by design (CPU-friendly), so it's less capable than the cloud Llama-3.3-70B path on long or technical transcripts.
95
+ - Fixed word-count chunking doesn't guarantee chunks align with real topic boundaries.
96
+ - `langdetect` can misclassify very short transcripts.
97
+
98
+ ## Possible next steps
99
+
100
+ - Add a quantitative evaluation pipeline (ROUGE-1/2/L or a small human-rated set) to formally compare phases and catch regressions.
101
+ - Try light fine-tuning of the local Qwen model on Arabic/English video-summary pairs.
102
+ - Move from fixed-size chunking to a topic/semantic-aware segmentation strategy.