Spaces:
Runtime error
Runtime error
Sukmadi commited on
Cleanup (#5)
Browse files* fix save to local
* remove prefix in utils
* update retrieval with faiss HNSW and better chunking
* save commit
* remove pdf plummer and minimalize requirements.txt
- .gitignore +2 -0
- README.md +5 -0
- app.py +10 -5
- app/app.py +22 -0
- app/generator.py +64 -42
- app/utils.py +0 -88
- chunks.txt +596 -0
- generator.py +71 -58
- requirements.txt +1 -1
- test/DeepLearning_mcq_output.json +194 -0
- test/ML_mcq_output.json +206 -0
- test/calculus_mcq_output.json +206 -0
- test/cerebras-api.py +8 -24
- test/context.md +12 -0
- test/general_mcq_output.json +664 -0
- test/mcq_output.json +121 -84
- test/oop_mcq_output.json +188 -0
- test/output.json +0 -0
- test/politic_mcq_output.json +206 -0
- test/raw_resp.json +33 -0
- test/test-api-key.py +79 -0
- test/text_chunks.md +1 -0
- utils.py +147 -3
.gitignore
CHANGED
|
@@ -1,5 +1,7 @@
|
|
| 1 |
.vscode
|
| 2 |
pdfs
|
|
|
|
|
|
|
| 3 |
|
| 4 |
*.png
|
| 5 |
*.jpg
|
|
|
|
| 1 |
.vscode
|
| 2 |
pdfs
|
| 3 |
+
app/__pycache__
|
| 4 |
+
|
| 5 |
|
| 6 |
*.png
|
| 7 |
*.jpg
|
README.md
CHANGED
|
@@ -8,3 +8,8 @@ pinned: false
|
|
| 8 |
---
|
| 9 |
|
| 10 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
---
|
| 9 |
|
| 10 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
| 11 |
+
|
| 12 |
+
---
|
| 13 |
+
TODO:
|
| 14 |
+
+ Apply COhen's Kappa to measure rate of aggreement between human and AI.
|
| 15 |
+
|
app.py
CHANGED
|
@@ -9,6 +9,7 @@ from pydantic import BaseModel
|
|
| 9 |
|
| 10 |
# Import the user's RAGMCQ implementation
|
| 11 |
from generator import RAGMCQ
|
|
|
|
| 12 |
|
| 13 |
app = FastAPI(title="RAG MCQ Generator API")
|
| 14 |
|
|
@@ -36,10 +37,7 @@ def startup_event():
|
|
| 36 |
global rag
|
| 37 |
|
| 38 |
# instantiate the heavy object once
|
| 39 |
-
rag = RAGMCQ(
|
| 40 |
-
qdrant_url=os.environ['QDRANT_URL'],
|
| 41 |
-
qdrant_api_key=os.environ['QDRANT_API_KEY']
|
| 42 |
-
)
|
| 43 |
print("RAGMCQ instance created on startup.")
|
| 44 |
|
| 45 |
@app.get("/health")
|
|
@@ -105,8 +103,12 @@ async def generate_saved_endpoint(
|
|
| 105 |
# don't fail the whole request for a validation error — return generator output and note the error
|
| 106 |
validation_report = {"error": f"Validation failed: {e}"}
|
| 107 |
|
|
|
|
|
|
|
| 108 |
return {"mcqs": mcqs, "validation": validation_report}
|
| 109 |
|
|
|
|
|
|
|
| 110 |
@app.post("/generate", response_model=GenerateResponse)
|
| 111 |
async def generate_endpoint(
|
| 112 |
background_tasks: BackgroundTasks,
|
|
@@ -141,7 +143,7 @@ async def generate_endpoint(
|
|
| 141 |
|
| 142 |
background_tasks.add_task(_cleanup, tmp_path)
|
| 143 |
|
| 144 |
-
# save pdf
|
| 145 |
try:
|
| 146 |
rag.save_pdf_to_qdrant(tmp_path, filename=qdrant_filename, collection=collection_name, overwrite=True)
|
| 147 |
except Exception as e:
|
|
@@ -171,6 +173,9 @@ async def generate_endpoint(
|
|
| 171 |
# don't fail the whole request for a validation error — return generator output and note the error
|
| 172 |
validation_report = {"error": f"Validation failed: {e}"}
|
| 173 |
|
|
|
|
|
|
|
|
|
|
| 174 |
return {"mcqs": mcqs, "validation": validation_report}
|
| 175 |
|
| 176 |
|
|
|
|
| 9 |
|
| 10 |
# Import the user's RAGMCQ implementation
|
| 11 |
from generator import RAGMCQ
|
| 12 |
+
from utils import log_pipeline
|
| 13 |
|
| 14 |
app = FastAPI(title="RAG MCQ Generator API")
|
| 15 |
|
|
|
|
| 37 |
global rag
|
| 38 |
|
| 39 |
# instantiate the heavy object once
|
| 40 |
+
rag = RAGMCQ()
|
|
|
|
|
|
|
|
|
|
| 41 |
print("RAGMCQ instance created on startup.")
|
| 42 |
|
| 43 |
@app.get("/health")
|
|
|
|
| 103 |
# don't fail the whole request for a validation error — return generator output and note the error
|
| 104 |
validation_report = {"error": f"Validation failed: {e}"}
|
| 105 |
|
| 106 |
+
log_pipeline('test/mcq_output.json', content={"mcqs": mcqs, "validation": validation_report})
|
| 107 |
+
|
| 108 |
return {"mcqs": mcqs, "validation": validation_report}
|
| 109 |
|
| 110 |
+
|
| 111 |
+
|
| 112 |
@app.post("/generate", response_model=GenerateResponse)
|
| 113 |
async def generate_endpoint(
|
| 114 |
background_tasks: BackgroundTasks,
|
|
|
|
| 143 |
|
| 144 |
background_tasks.add_task(_cleanup, tmp_path)
|
| 145 |
|
| 146 |
+
# save pdf
|
| 147 |
try:
|
| 148 |
rag.save_pdf_to_qdrant(tmp_path, filename=qdrant_filename, collection=collection_name, overwrite=True)
|
| 149 |
except Exception as e:
|
|
|
|
| 173 |
# don't fail the whole request for a validation error — return generator output and note the error
|
| 174 |
validation_report = {"error": f"Validation failed: {e}"}
|
| 175 |
|
| 176 |
+
|
| 177 |
+
log_pipeline('test/mcq_output.json', content={"mcqs": mcqs, "validation": validation_report})
|
| 178 |
+
|
| 179 |
return {"mcqs": mcqs, "validation": validation_report}
|
| 180 |
|
| 181 |
|
app/app.py
CHANGED
|
@@ -9,6 +9,7 @@ from pydantic import BaseModel
|
|
| 9 |
|
| 10 |
# Import the user's RAGMCQ implementation
|
| 11 |
from generator import RAGMCQ
|
|
|
|
| 12 |
|
| 13 |
app = FastAPI(title="RAG MCQ Generator API")
|
| 14 |
|
|
@@ -102,6 +103,16 @@ async def generate_saved_endpoint(
|
|
| 102 |
# don't fail the whole request for a validation error — return generator output and note the error
|
| 103 |
validation_report = {"error": f"Validation failed: {e}"}
|
| 104 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 105 |
return {"mcqs": mcqs, "validation": validation_report}
|
| 106 |
|
| 107 |
@app.post("/generate", response_model=GenerateResponse)
|
|
@@ -168,6 +179,17 @@ async def generate_endpoint(
|
|
| 168 |
# don't fail the whole request for a validation error — return generator output and note the error
|
| 169 |
validation_report = {"error": f"Validation failed: {e}"}
|
| 170 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 171 |
return {"mcqs": mcqs, "validation": validation_report}
|
| 172 |
|
| 173 |
|
|
|
|
| 9 |
|
| 10 |
# Import the user's RAGMCQ implementation
|
| 11 |
from generator import RAGMCQ
|
| 12 |
+
from utils import save_to_local, reset_token_count, get_token_count_record
|
| 13 |
|
| 14 |
app = FastAPI(title="RAG MCQ Generator API")
|
| 15 |
|
|
|
|
| 103 |
# don't fail the whole request for a validation error — return generator output and note the error
|
| 104 |
validation_report = {"error": f"Validation failed: {e}"}
|
| 105 |
|
| 106 |
+
print("Save result to ../test/mcq_output.json")
|
| 107 |
+
save_to_local('../test/mcq_output.json', content={"mcqs": mcqs, "validation": validation_report})
|
| 108 |
+
token_record = get_token_count_record()
|
| 109 |
+
|
| 110 |
+
print("Token Record:")
|
| 111 |
+
for record, value in token_record.items():
|
| 112 |
+
print(f'{record}:{value}', '\n')
|
| 113 |
+
|
| 114 |
+
reset_token_count()
|
| 115 |
+
|
| 116 |
return {"mcqs": mcqs, "validation": validation_report}
|
| 117 |
|
| 118 |
@app.post("/generate", response_model=GenerateResponse)
|
|
|
|
| 179 |
# don't fail the whole request for a validation error — return generator output and note the error
|
| 180 |
validation_report = {"error": f"Validation failed: {e}"}
|
| 181 |
|
| 182 |
+
print("Save result to ../test/mcq_output.json")
|
| 183 |
+
save_to_local('../test/mcq_output.json', content={"mcqs": mcqs, "validation": validation_report})
|
| 184 |
+
token_record = get_token_count_record()
|
| 185 |
+
|
| 186 |
+
print("Token Record:")
|
| 187 |
+
for record, value in token_record.items():
|
| 188 |
+
print(f'{record}:{value}', '\n')
|
| 189 |
+
|
| 190 |
+
reset_token_count()
|
| 191 |
+
# save_logs(token_record)
|
| 192 |
+
|
| 193 |
return {"mcqs": mcqs, "validation": validation_report}
|
| 194 |
|
| 195 |
|
app/generator.py
CHANGED
|
@@ -1,11 +1,13 @@
|
|
| 1 |
import re
|
| 2 |
import random
|
|
|
|
| 3 |
import numpy as np
|
| 4 |
-
|
|
|
|
| 5 |
from sentence_transformers import SentenceTransformer
|
| 6 |
from uuid import uuid4
|
| 7 |
import pymupdf4llm
|
| 8 |
-
|
| 9 |
|
| 10 |
try:
|
| 11 |
from qdrant_client import QdrantClient
|
|
@@ -28,19 +30,19 @@ try:
|
|
| 28 |
except Exception:
|
| 29 |
_HAS_FAISS = False
|
| 30 |
|
| 31 |
-
from utils import generate_mcqs_from_text, _post_chat, _safe_extract_json
|
| 32 |
|
| 33 |
class RAGMCQ:
|
| 34 |
def __init__(
|
| 35 |
self,
|
| 36 |
embedder_model: str = "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2",
|
| 37 |
-
|
| 38 |
-
qdrant_url: str =
|
| 39 |
-
qdrant_api_key: str =
|
| 40 |
qdrant_prefer_grpc: bool = False,
|
| 41 |
):
|
| 42 |
self.embedder = SentenceTransformer(embedder_model)
|
| 43 |
-
self.
|
| 44 |
self.embeddings = None # np.array of shape (N, D)
|
| 45 |
self.texts = [] # list of chunk texts
|
| 46 |
self.metadata = [] # list of dicts (page, chunk_id, char_range)
|
|
@@ -51,37 +53,45 @@ class RAGMCQ:
|
|
| 51 |
self.qdrant_url = qdrant_url
|
| 52 |
self.qdrant_api_key = qdrant_api_key
|
| 53 |
self.qdrant_prefer_grpc = qdrant_prefer_grpc
|
|
|
|
| 54 |
if qdrant_url:
|
| 55 |
self.connect_qdrant(qdrant_url, qdrant_api_key, qdrant_prefer_grpc)
|
| 56 |
|
| 57 |
def extract_pages(
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 75 |
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
txt = p.get("text", "") or ""
|
| 80 |
-
pages_md.append(txt.strip())
|
| 81 |
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
|
|
|
|
|
|
|
|
|
| 85 |
|
| 86 |
def chunk_text(self, text: str, max_chars: int = 1200) -> List[str]:
|
| 87 |
text = text.strip()
|
|
@@ -89,7 +99,7 @@ class RAGMCQ:
|
|
| 89 |
return []
|
| 90 |
if len(text) <= max_chars:
|
| 91 |
return [text]
|
| 92 |
-
|
| 93 |
# split by sentence-like boundaries
|
| 94 |
sentences = re.split(r'(?<=[\.\?\!])\s+', text)
|
| 95 |
chunks = []
|
|
@@ -116,6 +126,7 @@ class RAGMCQ:
|
|
| 116 |
|
| 117 |
def build_index_from_pdf(self, pdf_path: str, max_chars: int = 1200):
|
| 118 |
pages = self.extract_pages(pdf_path)
|
|
|
|
| 119 |
self.texts = []
|
| 120 |
self.metadata = []
|
| 121 |
|
|
@@ -128,6 +139,8 @@ class RAGMCQ:
|
|
| 128 |
if not self.texts:
|
| 129 |
raise RuntimeError("No text extracted from PDF.")
|
| 130 |
|
|
|
|
|
|
|
| 131 |
# compute embeddings
|
| 132 |
emb = self.embedder.encode(self.texts, convert_to_numpy=True, show_progress_bar=True)
|
| 133 |
self.embeddings = emb.astype("float32")
|
|
@@ -187,7 +200,7 @@ class RAGMCQ:
|
|
| 187 |
# ask generator
|
| 188 |
try:
|
| 189 |
mcq_block = generate_mcqs_from_text(
|
| 190 |
-
chunk_text, n=to_gen, model=self.
|
| 191 |
)
|
| 192 |
except Exception as e:
|
| 193 |
# skip this chunk if generator fails
|
|
@@ -199,7 +212,7 @@ class RAGMCQ:
|
|
| 199 |
output[str(qcount)] = mcq_block[item]
|
| 200 |
if qcount >= n_questions:
|
| 201 |
return output
|
| 202 |
-
|
| 203 |
return output
|
| 204 |
|
| 205 |
elif mode == "rag":
|
|
@@ -214,6 +227,10 @@ class RAGMCQ:
|
|
| 214 |
# create a seed query: pick a random chunk, pick a sentence from it
|
| 215 |
seed_idx = random.randrange(len(self.texts))
|
| 216 |
chunk = self.texts[seed_idx]
|
|
|
|
|
|
|
|
|
|
|
|
|
| 217 |
sents = re.split(r'(?<=[\.\?\!])\s+', chunk)
|
| 218 |
seed_sent = random.choice([s for s in sents if len(s.strip()) > 20]) if sents else chunk[:200]
|
| 219 |
query = f"Create questions about: {seed_sent}"
|
|
@@ -226,12 +243,16 @@ class RAGMCQ:
|
|
| 226 |
context_parts.append(f"[page {md['page']}] {self.texts[ridx]}")
|
| 227 |
context = "\n\n".join(context_parts)
|
| 228 |
|
|
|
|
|
|
|
|
|
|
| 229 |
# call generator for 1 question (or small batch) with the retrieved context
|
| 230 |
try:
|
| 231 |
# request 1 question at a time to keep diversity
|
| 232 |
mcq_block = generate_mcqs_from_text(
|
| 233 |
-
context, n=1, model=self.
|
| 234 |
)
|
|
|
|
| 235 |
except Exception as e:
|
| 236 |
print(f"Generator failed during RAG attempt {attempts}: {e}")
|
| 237 |
continue
|
|
@@ -242,7 +263,7 @@ class RAGMCQ:
|
|
| 242 |
output[str(qcount)] = mcq_block[item]
|
| 243 |
if qcount >= n_questions:
|
| 244 |
return output
|
| 245 |
-
|
| 246 |
return output
|
| 247 |
else:
|
| 248 |
raise ValueError("mode must be 'per_page' or 'rag'.")
|
|
@@ -281,7 +302,7 @@ class RAGMCQ:
|
|
| 281 |
system = {
|
| 282 |
"role": "system",
|
| 283 |
"content": (
|
| 284 |
-
"Bạn là một trợ lý đánh giá tính thực chứng của câu hỏi trắc nghiệm dựa trên đoạn văn được cung cấp. "
|
| 285 |
"Hãy trả lời DUY NHẤT bằng JSON hợp lệ (không có văn bản khác) theo schema:\n\n"
|
| 286 |
"{\n"
|
| 287 |
' "supported": true/false, # câu trả lời đúng có được nội dung chứng thực không\n'
|
|
@@ -303,7 +324,7 @@ class RAGMCQ:
|
|
| 303 |
)
|
| 304 |
}
|
| 305 |
|
| 306 |
-
raw = _post_chat([system, user], model=self.
|
| 307 |
|
| 308 |
# parse JSON object in response
|
| 309 |
try:
|
|
@@ -397,6 +418,7 @@ class RAGMCQ:
|
|
| 397 |
|
| 398 |
# extract pages and chunks (re-using your existing helpers)
|
| 399 |
pages = self.extract_pages(pdf_path)
|
|
|
|
| 400 |
all_chunks = []
|
| 401 |
all_meta = []
|
| 402 |
for p_idx, page_text in enumerate(pages, start=1):
|
|
@@ -406,7 +428,7 @@ class RAGMCQ:
|
|
| 406 |
all_meta.append({"page": p_idx, "chunk_id": cid, "length": len(ch)})
|
| 407 |
|
| 408 |
if not all_chunks:
|
| 409 |
-
raise RuntimeError("No
|
| 410 |
|
| 411 |
# ensure collection exists
|
| 412 |
self._ensure_collection(collection)
|
|
@@ -640,7 +662,7 @@ class RAGMCQ:
|
|
| 640 |
continue
|
| 641 |
to_gen = questions_per_chunk
|
| 642 |
try:
|
| 643 |
-
mcq_block = generate_mcqs_from_text(txt, n=to_gen, model=self.
|
| 644 |
except Exception as e:
|
| 645 |
print(f"Generator failed on chunk (index {i}): {e}")
|
| 646 |
continue
|
|
@@ -680,7 +702,7 @@ class RAGMCQ:
|
|
| 680 |
context = "\n\n".join(context_parts)
|
| 681 |
|
| 682 |
try:
|
| 683 |
-
mcq_block = generate_mcqs_from_text(context, n=1, model=self.
|
| 684 |
except Exception as e:
|
| 685 |
print(f"Generator failed during RAG attempt {attempts}: {e}")
|
| 686 |
continue
|
|
|
|
| 1 |
import re
|
| 2 |
import random
|
| 3 |
+
import fitz
|
| 4 |
import numpy as np
|
| 5 |
+
import os
|
| 6 |
+
from typing import List, Optional, Tuple, Dict, Any
|
| 7 |
from sentence_transformers import SentenceTransformer
|
| 8 |
from uuid import uuid4
|
| 9 |
import pymupdf4llm
|
| 10 |
+
from utils import save_to_local
|
| 11 |
|
| 12 |
try:
|
| 13 |
from qdrant_client import QdrantClient
|
|
|
|
| 30 |
except Exception:
|
| 31 |
_HAS_FAISS = False
|
| 32 |
|
| 33 |
+
from utils import generate_mcqs_from_text, _post_chat, _safe_extract_json, save_to_local
|
| 34 |
|
| 35 |
class RAGMCQ:
|
| 36 |
def __init__(
|
| 37 |
self,
|
| 38 |
embedder_model: str = "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2",
|
| 39 |
+
generation_model: str = "gpt-oss-120b",
|
| 40 |
+
qdrant_url: str = os.environ.get('QDRANT_URL') or "",
|
| 41 |
+
qdrant_api_key: str = os.environ.get('QDRANT_API_KEY') or "",
|
| 42 |
qdrant_prefer_grpc: bool = False,
|
| 43 |
):
|
| 44 |
self.embedder = SentenceTransformer(embedder_model)
|
| 45 |
+
self.generation_model = generation_model
|
| 46 |
self.embeddings = None # np.array of shape (N, D)
|
| 47 |
self.texts = [] # list of chunk texts
|
| 48 |
self.metadata = [] # list of dicts (page, chunk_id, char_range)
|
|
|
|
| 53 |
self.qdrant_url = qdrant_url
|
| 54 |
self.qdrant_api_key = qdrant_api_key
|
| 55 |
self.qdrant_prefer_grpc = qdrant_prefer_grpc
|
| 56 |
+
|
| 57 |
if qdrant_url:
|
| 58 |
self.connect_qdrant(qdrant_url, qdrant_api_key, qdrant_prefer_grpc)
|
| 59 |
|
| 60 |
def extract_pages(
|
| 61 |
+
self,
|
| 62 |
+
pdf_path: str,
|
| 63 |
+
*,
|
| 64 |
+
pages: Optional[List[int]] = None,
|
| 65 |
+
ignore_images: bool = False,
|
| 66 |
+
dpi: int = 150
|
| 67 |
+
) -> List[str]:
|
| 68 |
+
doc = fitz.open(pdf_path)
|
| 69 |
+
try:
|
| 70 |
+
# request page-wise output (page_chunks=True -> list[dict] per page)
|
| 71 |
+
page_dicts = pymupdf4llm.to_markdown(
|
| 72 |
+
doc,
|
| 73 |
+
pages=pages,
|
| 74 |
+
ignore_images=ignore_images,
|
| 75 |
+
dpi=dpi,
|
| 76 |
+
page_chunks=True,
|
| 77 |
+
)
|
| 78 |
+
|
| 79 |
+
# to_markdown(..., page_chunks=True) returns a list of dicts, each has key "text" (markdown)
|
| 80 |
+
pages_md: List[str] = []
|
| 81 |
+
for p in page_dicts:
|
| 82 |
+
txt = p.get("text", "") or ""
|
| 83 |
+
pages_md.append(txt.strip())
|
| 84 |
|
| 85 |
+
return pages_md
|
| 86 |
+
finally:
|
| 87 |
+
doc.close()
|
|
|
|
|
|
|
| 88 |
|
| 89 |
+
# pages = []
|
| 90 |
+
# with pdfplumber.open(pdf_path) as pdf:
|
| 91 |
+
# for p in pdf.pages:
|
| 92 |
+
# txt = p.extract_text() or ""
|
| 93 |
+
# pages.append(txt.strip())
|
| 94 |
+
# return pages
|
| 95 |
|
| 96 |
def chunk_text(self, text: str, max_chars: int = 1200) -> List[str]:
|
| 97 |
text = text.strip()
|
|
|
|
| 99 |
return []
|
| 100 |
if len(text) <= max_chars:
|
| 101 |
return [text]
|
| 102 |
+
|
| 103 |
# split by sentence-like boundaries
|
| 104 |
sentences = re.split(r'(?<=[\.\?\!])\s+', text)
|
| 105 |
chunks = []
|
|
|
|
| 126 |
|
| 127 |
def build_index_from_pdf(self, pdf_path: str, max_chars: int = 1200):
|
| 128 |
pages = self.extract_pages(pdf_path)
|
| 129 |
+
|
| 130 |
self.texts = []
|
| 131 |
self.metadata = []
|
| 132 |
|
|
|
|
| 139 |
if not self.texts:
|
| 140 |
raise RuntimeError("No text extracted from PDF.")
|
| 141 |
|
| 142 |
+
save_to_local('../test/text_chunks.md', file_content=self.texts)
|
| 143 |
+
|
| 144 |
# compute embeddings
|
| 145 |
emb = self.embedder.encode(self.texts, convert_to_numpy=True, show_progress_bar=True)
|
| 146 |
self.embeddings = emb.astype("float32")
|
|
|
|
| 200 |
# ask generator
|
| 201 |
try:
|
| 202 |
mcq_block = generate_mcqs_from_text(
|
| 203 |
+
chunk_text, n=to_gen, model=self.generation_model, temperature=temperature
|
| 204 |
)
|
| 205 |
except Exception as e:
|
| 206 |
# skip this chunk if generator fails
|
|
|
|
| 212 |
output[str(qcount)] = mcq_block[item]
|
| 213 |
if qcount >= n_questions:
|
| 214 |
return output
|
| 215 |
+
|
| 216 |
return output
|
| 217 |
|
| 218 |
elif mode == "rag":
|
|
|
|
| 227 |
# create a seed query: pick a random chunk, pick a sentence from it
|
| 228 |
seed_idx = random.randrange(len(self.texts))
|
| 229 |
chunk = self.texts[seed_idx]
|
| 230 |
+
|
| 231 |
+
#? Investigate Chunking Strategy
|
| 232 |
+
with open("chunks.txt", "a", encoding="utf-8") as f: f.write(chunk + "\n")
|
| 233 |
+
|
| 234 |
sents = re.split(r'(?<=[\.\?\!])\s+', chunk)
|
| 235 |
seed_sent = random.choice([s for s in sents if len(s.strip()) > 20]) if sents else chunk[:200]
|
| 236 |
query = f"Create questions about: {seed_sent}"
|
|
|
|
| 243 |
context_parts.append(f"[page {md['page']}] {self.texts[ridx]}")
|
| 244 |
context = "\n\n".join(context_parts)
|
| 245 |
|
| 246 |
+
save_to_local('../test/context.md', context)
|
| 247 |
+
|
| 248 |
+
|
| 249 |
# call generator for 1 question (or small batch) with the retrieved context
|
| 250 |
try:
|
| 251 |
# request 1 question at a time to keep diversity
|
| 252 |
mcq_block = generate_mcqs_from_text(
|
| 253 |
+
context, n=1, model=self.generation_model, temperature=temperature
|
| 254 |
)
|
| 255 |
+
|
| 256 |
except Exception as e:
|
| 257 |
print(f"Generator failed during RAG attempt {attempts}: {e}")
|
| 258 |
continue
|
|
|
|
| 263 |
output[str(qcount)] = mcq_block[item]
|
| 264 |
if qcount >= n_questions:
|
| 265 |
return output
|
| 266 |
+
|
| 267 |
return output
|
| 268 |
else:
|
| 269 |
raise ValueError("mode must be 'per_page' or 'rag'.")
|
|
|
|
| 302 |
system = {
|
| 303 |
"role": "system",
|
| 304 |
"content": (
|
| 305 |
+
"Bạn là một trợ lý đánh giá tính thực chứng của câu hỏi trắc nghiệm dựa trên đoạn văn được cung cấp. Luôn trả lời bằng Tiếng Việt"
|
| 306 |
"Hãy trả lời DUY NHẤT bằng JSON hợp lệ (không có văn bản khác) theo schema:\n\n"
|
| 307 |
"{\n"
|
| 308 |
' "supported": true/false, # câu trả lời đúng có được nội dung chứng thực không\n'
|
|
|
|
| 324 |
)
|
| 325 |
}
|
| 326 |
|
| 327 |
+
raw = _post_chat([system, user], model=self.generation_model, temperature=model_verification_temperature)
|
| 328 |
|
| 329 |
# parse JSON object in response
|
| 330 |
try:
|
|
|
|
| 418 |
|
| 419 |
# extract pages and chunks (re-using your existing helpers)
|
| 420 |
pages = self.extract_pages(pdf_path)
|
| 421 |
+
|
| 422 |
all_chunks = []
|
| 423 |
all_meta = []
|
| 424 |
for p_idx, page_text in enumerate(pages, start=1):
|
|
|
|
| 428 |
all_meta.append({"page": p_idx, "chunk_id": cid, "length": len(ch)})
|
| 429 |
|
| 430 |
if not all_chunks:
|
| 431 |
+
raise RuntimeError("No tSext extracted from PDF.")
|
| 432 |
|
| 433 |
# ensure collection exists
|
| 434 |
self._ensure_collection(collection)
|
|
|
|
| 662 |
continue
|
| 663 |
to_gen = questions_per_chunk
|
| 664 |
try:
|
| 665 |
+
mcq_block = generate_mcqs_from_text(txt, n=to_gen, model=self.generation_model, temperature=temperature)
|
| 666 |
except Exception as e:
|
| 667 |
print(f"Generator failed on chunk (index {i}): {e}")
|
| 668 |
continue
|
|
|
|
| 702 |
context = "\n\n".join(context_parts)
|
| 703 |
|
| 704 |
try:
|
| 705 |
+
mcq_block = generate_mcqs_from_text(context, n=1, model=self.generation_model, temperature=temperature)
|
| 706 |
except Exception as e:
|
| 707 |
print(f"Generator failed during RAG attempt {attempts}: {e}")
|
| 708 |
continue
|
app/utils.py
DELETED
|
@@ -1,88 +0,0 @@
|
|
| 1 |
-
import re
|
| 2 |
-
import json
|
| 3 |
-
from typing import Dict, Any
|
| 4 |
-
import requests
|
| 5 |
-
import os
|
| 6 |
-
|
| 7 |
-
#TODO: allow to choose different provider later + dynamic routing when token expired
|
| 8 |
-
API_URL = "https://api.cerebras.ai/v1/chat/completions"
|
| 9 |
-
CEREBRAS_API_KEY = os.environ['CEREBRAS_API_KEY']
|
| 10 |
-
|
| 11 |
-
HEADERS = {"Authorization": f"Bearer {CEREBRAS_API_KEY}"}
|
| 12 |
-
JSON_OBJ_RE = re.compile(r"(\{[\s\S]*\})", re.MULTILINE)
|
| 13 |
-
|
| 14 |
-
def _post_chat(messages: list, model: str, temperature: float = 0.2, timeout: int = 60) -> str:
|
| 15 |
-
payload = {"model": model, "messages": messages, "temperature": temperature}
|
| 16 |
-
resp = requests.post(API_URL, headers=HEADERS, json=payload, timeout=timeout)
|
| 17 |
-
resp.raise_for_status()
|
| 18 |
-
data = resp.json()
|
| 19 |
-
|
| 20 |
-
# handle various shapes
|
| 21 |
-
if "choices" in data and len(data["choices"]) > 0:
|
| 22 |
-
# prefer message.content
|
| 23 |
-
ch = data["choices"][0]
|
| 24 |
-
|
| 25 |
-
if isinstance(ch, dict) and "message" in ch and "content" in ch["message"]:
|
| 26 |
-
return ch["message"]["content"]
|
| 27 |
-
|
| 28 |
-
if "text" in ch:
|
| 29 |
-
return ch["text"]
|
| 30 |
-
|
| 31 |
-
# final fallback
|
| 32 |
-
raise RuntimeError("Unexpected HF response shape: " + json.dumps(data)[:200])
|
| 33 |
-
|
| 34 |
-
def _safe_extract_json(text: str) -> dict:
|
| 35 |
-
# remove triple backticks
|
| 36 |
-
text = re.sub(r"```(?:json)?\n?", "", text)
|
| 37 |
-
m = JSON_OBJ_RE.search(text)
|
| 38 |
-
|
| 39 |
-
if not m:
|
| 40 |
-
raise ValueError("No JSON object found in model output.")
|
| 41 |
-
js = m.group(1)
|
| 42 |
-
|
| 43 |
-
# try load, fix trailing commas
|
| 44 |
-
try:
|
| 45 |
-
return json.loads(js)
|
| 46 |
-
except json.JSONDecodeError:
|
| 47 |
-
fixed = re.sub(r",\s*([}\]])", r"\1", js)
|
| 48 |
-
return json.loads(fixed)
|
| 49 |
-
|
| 50 |
-
def generate_mcqs_from_text(
|
| 51 |
-
source_text: str,
|
| 52 |
-
n: int = 3,
|
| 53 |
-
model: str = "gpt-oss-120b",
|
| 54 |
-
temperature: float = 0.2,
|
| 55 |
-
) -> Dict[str, Any]:
|
| 56 |
-
system_message = {
|
| 57 |
-
"role": "system",
|
| 58 |
-
"content": (
|
| 59 |
-
"Bạn là một trợ lý hữu ích chuyên tạo câu hỏi trắc nghiệm. "
|
| 60 |
-
"Chỉ TRẢ VỀ duy nhất một đối tượng JSON theo đúng schema sau và không có bất kỳ văn bản nào khác:\n\n"
|
| 61 |
-
"{\n"
|
| 62 |
-
' "1": { "câu hỏi": "...", "lựa chọn": {"a":"...","b":"...","c":"...","d":"..."}, "đáp án":"..."},\n'
|
| 63 |
-
' "2": { ... }\n'
|
| 64 |
-
"}\n\n"
|
| 65 |
-
"Lưu ý:\n"
|
| 66 |
-
f"- Tạo đúng {n} mục, đánh YOUR_API_KEYsố từ 1 tới {n}.\n"
|
| 67 |
-
"- Khóa 'lựa chọn' phải có các phím a, b, c, d.\n"
|
| 68 |
-
"- 'đáp án' phải là toàn văn đáp án đúng (không phải ký tự chữ cái), và giá trị này phải khớp chính xác với một trong các giá trị trong 'lựa chọn'.\n"
|
| 69 |
-
"- Không kèm giải thích hay trường thêm.\n"
|
| 70 |
-
"- Các phương án sai (distractors) phải hợp lý và không lặp lại."
|
| 71 |
-
)
|
| 72 |
-
}
|
| 73 |
-
user_message = {
|
| 74 |
-
"role": "user",
|
| 75 |
-
"content": (
|
| 76 |
-
f"Hãy tạo {n} câu hỏi trắc nghiệm từ nội dung dưới đây. Dùng nội dung này làm nguồn duy nhất để trả lời."
|
| 77 |
-
"Nếu nội dung quá ít để tạo câu hỏi chính xác, hãy tạo các phương án hợp lý nhưng có thể biện minh được.\n\n"
|
| 78 |
-
f"Nội dung:\n\n{source_text}"
|
| 79 |
-
)
|
| 80 |
-
}
|
| 81 |
-
|
| 82 |
-
raw = _post_chat([system_message, user_message], model=model, temperature=temperature)
|
| 83 |
-
parsed = _safe_extract_json(raw)
|
| 84 |
-
|
| 85 |
-
# validate structure and length
|
| 86 |
-
if not isinstance(parsed, dict) or len(parsed) != n:
|
| 87 |
-
raise ValueError(f"Generator returned invalid structure. Raw:\n{raw}")
|
| 88 |
-
return parsed
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
chunks.txt
ADDED
|
@@ -0,0 +1,596 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
_MỤC LỤC_ _3_
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
2.3 Các công thức tính tích phân mặt loại II . . . . . . . . . . . . . . . . . 153
|
| 5 |
+
|
| 6 |
+
2.4 Công thức Ostrogradsky . . . . . . . . . . . . . . . . . . . . . . . . . . 157
|
| 7 |
+
|
| 8 |
+
2.5 Công thức Stokes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
|
| 9 |
+
|
| 10 |
+
2.6 Công thức liên hệgiữa tích phân mặt loại I và loại II . . . . . . . . . 161
|
| 11 |
+
**Chương 6 . Lý thuyết trường. . . . . . . . . . . . . . . . . . . . . . . . . 165**
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
1 Trường vô hướng . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
|
| 15 |
+
|
| 16 |
+
1.1 Định nghĩa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
|
| 17 |
+
|
| 18 |
+
1.2 Đạo hàm theo hướng . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
|
| 19 |
+
|
| 20 |
+
1.3 Gradient . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
|
| 21 |
+
|
| 22 |
+
1.4 Bài tập . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
|
| 23 |
+
|
| 24 |
+
2 Trường véctơ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
|
| 25 |
+
|
| 26 |
+
2.1 Định nghĩa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
|
| 27 |
+
2.2 Thông lượng, dive, trường ống . . . . . . . . . . . . . . . . . . . . . . . 169
|
| 28 |
+
|
| 29 |
+
2.3 Hoàn lưu, véctơ xoáy . . . . . . . . . . . . . . .
|
| 30 |
+
**Phương trình tiếp diện của mặt cong cho bởi phương trình tham số**
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
Bài toán: Tìm mặt phẳng tiếp diện của mặt cong S cho bởi phương trình tham số
|
| 34 |
+
|
| 35 |
+
|
| 36 |
+
r ( u, v ) = x ( u, v ) . [⃗] i + y ( t ) . [⃗] j + z ( t ) . [⃗] k
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
tại điểm P 0 ứng với u = u 0, v = v 0 . 16
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
x = a sin [2] t
|
| 60 |
+
y = b sin t cos t tại điểm ứng với t = _[π]_ 4 [,] [ (] [a][,][ b][,][ c] [ >] [ 0] [)] [.]
|
| 61 |
+
z = c cos [2] t
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
|
| 65 |
+
x = [e] [t] [ sin][ t]
|
| 66 |
+
~~√~~ 2
|
| 67 |
+
|
| 68 |
+
y = 1
|
| 69 |
+
z = [e] [t] [ cos][ t]
|
| 70 |
+
~~√~~ 2
|
| 71 |
+
|
| 72 |
+
|
| 73 |
+
|
| 74 |
+
tại điểm ứng với t = 0. [a]
|
| 75 |
+
|
| 76 |
+
2 = [y] [−] 2 [b]
|
| 77 |
+
a 0
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
|
| 81 |
+
2
|
| 82 |
+
|
| 83 |
+
− c
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
|
| 87 |
+
_Lời giải_ . a. **–** Phương trình tiếp tuyến: ( d ) : [x] [−] 2 [a]
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
|
| 91 |
+
0 2 = [z] − [−] c 2 [c]
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
|
| 95 |
+
**–** Phương trình pháp diện: ( P ) : a �x − 2 [a]
|
| 96 |
+
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
[c] = 0. 2 �
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
|
| 104 |
+
|
| 105 |
+
[a] − c z − [c]
|
| 106 |
+
|
| 107 |
+
2 � � 2
|
| 108 |
+
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
x = [y] [−] [1]
|
| 112 |
+
|
| 113 |
+
2 0
|
| 114 |
+
2
|
| 115 |
+
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
2
|
| 119 |
+
2
|
| 120 |
+
~~√~~ 2
|
| 121 |
+
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
2 . 2
|
| 125 |
+
|
| 126 |
+
|
| 127 |
+
|
| 128 |
+
b. **–** Phương trình tiếp tuyến: ( d ) : ~~√~~ x
|
| 129 |
+
|
| 130 |
+
|
| 131 |
+
|
| 132 |
+
√
|
| 133 |
+
|
| 134 |
+
[−] [1] = [z] [−] 2
|
| 135 |
+
|
| 136 |
+
0 ~~√~~ 2
|
| 137 |
+
|
| 138 |
+
|
| 139 |
+
|
| 140 |
+
**–** Phương trình pháp diện: ( P ) : √
|
| 141 |
+
|
| 142 |
+
|
| 143 |
+
|
| 144 |
+
2 √
|
| 145 |
+
z −
|
| 146 |
+
2 2
|
| 147 |
+
�
|
| 148 |
+
|
| 149 |
+
|
| 150 |
+
|
| 151 |
+
2 √
|
| 152 |
+
2 [x] [ +] 2
|
| 153 |
+
|
| 154 |
+
|
| 155 |
+
|
| 156 |
+
2
|
| 157 |
+
= 0. 2
|
| 158 |
+
�
|
| 159 |
+
|
| 160 |
+
|
| 161 |
+
|
| 162 |
+
**Bài tập 1.6.** Viết phương trình pháp tuyến và tiếp diện của mặt cong:
|
| 163 |
+
|
| 164 |
+
|
| 165 |
+
a) x [2] − 4y [2] + 2z [2] = 6 tại điểm ( 2, 2, 3 ) . b) z = 2x [2] + 4y [2] tại điểm ( 2, 1, 12 ) . c) z = ln ( 2x + y ) tại điểm (− 1, 3, 0 )
|
| 166 |
+
|
| 167 |
+
|
| 168 |
+
20
|
| 169 |
+
Ta có
|
| 170 |
+
N ⃗ ( t ) = _[γ]_ [′] [(] [t] [)]
|
| 171 |
+
|
| 172 |
+
| _γ_ ( t )|
|
| 173 |
+
|
| 174 |
+
|
| 175 |
+
nên
|
| 176 |
+
N [′] ( t ) =
|
| 177 |
+
|
| 178 |
+
#### 2.4 Mặt cong trong không gian R [3]
|
| 179 |
+
|
| 180 |
+
|
| 181 |
+
Tương tựnhư cách chúng ta biểu diễn đường cong trong không gian bởi một hàm véc tơ
|
| 182 |
+
một tham số r ( t ) = x ( t ) . [⃗] i + y ( t ) . [⃗] j + z ( t ) . [⃗] k, mỗi mặt cong trong không gian được biểu diễn
|
| 183 |
+
tham sốdưới dạng
|
| 184 |
+
r ( u, v ) = x ( u, v ) . [⃗] i + y ( t ) . [⃗] j + z ( t ) . [⃗] k,
|
| 185 |
+
|
| 186 |
+
|
| 187 |
+
tức là một hàm véc tơ phụthuộc vào hai tham số u, v. 15
|
| 188 |
+
. . 23
|
| 189 |
+
|
| 190 |
+
1.1 Định nghĩa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
|
| 191 |
+
|
| 192 |
+
1.2 Tính tích phân kép trong hệtoạđộDescartes . . . . . . . . . . . . . . 28
|
| 193 |
+
1.3 Phép đổi biến sốtrong tích phân kép . . . . . . . . . . . . . . . . . . . 39
|
| 194 |
+
|
| 195 |
+
1.4 Bài tập ôn tập . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
|
| 196 |
+
|
| 197 |
+
2 Tích phân bội ba . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
|
| 198 |
+
2.1 Định nghĩa và tính chất . . . . . . . . . . . . . . . . . . . . . . . . . . 54
|
| 199 |
+
|
| 200 |
+
2.2 Tính tích phân bội ba trong hệtoạđộDescartes . . . . . . . . . . . . 54
|
| 201 |
+
2.3 Đổi biến sốtrong tích phân bội ba . . . . . . . . . . . . . . . . . . . . . 58
|
| 202 |
+
|
| 203 |
+
2.4 Bài tập ôn tập . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
|
| 204 |
+
|
| 205 |
+
3 Các ứng dụng của tích phân bội . . . . . . . . . . . . . . . . . . . . . . . . . . 76
|
| 206 |
+
3.1 Tính diện tích hình phẳng . . . . . . . . . . . . . . . . . . . . . . . . . 76
|
| 207 |
+
3.2 Tính thểtích vật thể . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
|
| 208 |
+
|
| 209 |
+
3.3 Tính diện tích mặt cong . . . . . . . . . . . . . . . . . . . . . . . . . . 89
|
| 210 |
+
|
| 211 |
+
|
| 212 |
+
1
|
| 213 |
+
**AI VIETNAM** **aivietnam.edu.vn**
|
| 214 |
+
|
| 215 |
+
|
| 216 |
+
Cảhai biến age ởlần in đầu tiên đều là biến cục bộvì Python sẽưu tiên tìm biến cục bộtrước,
|
| 217 |
+
ởđây là đối số2 truyền vào age. Vì ta không định nghĩa self.age, nên khi gọi, Python sẽtìm đến
|
| 218 |
+
thứtựtiếp theo là biến Class. Chính vì vậy, ta sẽin ra được kết quảage = 1
|
| 219 |
+
|
| 220 |
+
|
| 221 |
+
**1.1.2** **Biến toàn cục (Global)**
|
| 222 |
+
|
| 223 |
+
|
| 224 |
+
Biến toàn cục được khai báo bên ngoài hàm hoặc class, sửdụng được trên toàn chương trình
|
| 225 |
+
nhưng nên hạn chếđểtránh gây khó kiểm soát. **Không khuyến khích:**
|
| 226 |
+
|
| 227 |
+
|
| 228 |
+
1 `counter = 0` `# Global variable`
|
| 229 |
+
|
| 230 |
+
|
| 231 |
+
2
|
| 232 |
+
|
| 233 |
+
|
| 234 |
+
3 `class MyClass:`
|
| 235 |
+
|
| 236 |
+
4 `def increment(self):`
|
| 237 |
+
|
| 238 |
+
|
| 239 |
+
5 `global counter`
|
| 240 |
+
|
| 241 |
+
|
| 242 |
+
6 `counter += 1`
|
| 243 |
+
|
| 244 |
+
|
| 245 |
+
**Khuyến khích:**
|
| 246 |
+
|
| 247 |
+
|
| 248 |
+
1 `class MyClass:`
|
| 249 |
+
|
| 250 |
+
|
| 251 |
+
2 `counter = 0` `# Class attribute`
|
| 252 |
+
|
| 253 |
+
|
| 254 |
+
3
|
| 255 |
+
|
| 256 |
+
|
| 257 |
+
4 `def increment(self):`
|
| 258 |
+
|
| 259 |
+
|
| 260 |
+
5 `MyClass.counter += 1`
|
| 261 |
+
|
| 262 |
+
### **2 Động lực cho sựra đời của OOP**
|
| 263 |
+
|
| 264 |
+
|
| 265 |
+
Trong thực tế, chúng ta luôn tìm cách mô hình hóa các thực thểthực tếthành các đối tượng số
|
| 266 |
+
hóa. Từnhu cầu quản lý và tổchức các thực thểnày, lập trình hướng đối tượng ra đời đểđơn
|
| 267 |
+
giản hóa và tối ưu hóa việc xây dựng phần mềm. Hãy tưởng tượng một thếgiới mạng xã hội, nơi mỗi người dùng chính là một đối tượng (object). Những thông tin như ngày sinh, giới tính, sốđiện thoại...
|
| 268 |
+
ập
|
| 269 |
+
được. - **Biến** **`private`** là thông tin tuyệt mật – chỉlớp khai báo nó mới có quyền truy cập. Lớp
|
| 270 |
+
con không thể“đọc nhật ký” hay can thiệp trực tiếp vào những gì cha mẹkhông cho phép. - **Biến** **`protected`** thì đặc biệt hơn – đây là những “di sản” được truyền lại, chỉdành cho
|
| 271 |
+
các lớp con và không ai khác ngoài hệthống kếthừa được phép sửdụng. Sựphân cấp này giúp bảo vệdữliệu và giữcho hệthống kếthừa hoạt động có tổchức. 7
|
| 272 |
+
**AI VIETNAM** **aivietnam.edu.vn**
|
| 273 |
+
|
| 274 |
+
|
| 275 |
+
Cảhai biến age ởlần in đầu tiên đều là biến cục bộvì Python sẽưu tiên tìm biến cục bộtrước,
|
| 276 |
+
ởđây là đối số2 truyền vào age. Vì ta không định nghĩa self.age, nên khi gọi, Python sẽtìm đến
|
| 277 |
+
thứtựtiếp theo là biến Class. Chính vì vậy, ta sẽin ra được kết quảage = 1
|
| 278 |
+
|
| 279 |
+
|
| 280 |
+
**1.1.2** **Biến toàn cục (Global)**
|
| 281 |
+
|
| 282 |
+
|
| 283 |
+
Biến toàn cục được khai báo bên ngoài hàm hoặc class, sửdụng được trên toàn chương trình
|
| 284 |
+
nhưng nên hạn chếđểtránh gây khó kiểm soát. **Không khuyến khích:**
|
| 285 |
+
|
| 286 |
+
|
| 287 |
+
1 `counter = 0` `# Global variable`
|
| 288 |
+
|
| 289 |
+
|
| 290 |
+
2
|
| 291 |
+
|
| 292 |
+
|
| 293 |
+
3 `class MyClass:`
|
| 294 |
+
|
| 295 |
+
4 `def increment(self):`
|
| 296 |
+
|
| 297 |
+
|
| 298 |
+
5 `global counter`
|
| 299 |
+
|
| 300 |
+
|
| 301 |
+
6 `counter += 1`
|
| 302 |
+
|
| 303 |
+
|
| 304 |
+
**Khuyến khích:**
|
| 305 |
+
|
| 306 |
+
|
| 307 |
+
1 `class MyClass:`
|
| 308 |
+
|
| 309 |
+
|
| 310 |
+
2 `counter = 0` `# Class attribute`
|
| 311 |
+
|
| 312 |
+
|
| 313 |
+
3
|
| 314 |
+
|
| 315 |
+
|
| 316 |
+
4 `def increment(self):`
|
| 317 |
+
|
| 318 |
+
|
| 319 |
+
5 `MyClass.counter += 1`
|
| 320 |
+
|
| 321 |
+
### **2 Động lực cho sựra đời của OOP**
|
| 322 |
+
|
| 323 |
+
|
| 324 |
+
Trong thực tế, chúng ta luôn tìm cách mô hình hóa các thực thểthực tếthành các đối tượng số
|
| 325 |
+
hóa. Từnhu cầu quản lý và tổchức các thực thểnày, lập trình hướng đối tượng ra đời đểđơn
|
| 326 |
+
giản hóa và tối ưu hóa việc xây dựng phần mềm. Hãy tưởng tượng một thếgiới mạng xã hội, nơi mỗi người dùng chính là một đối tượng (object). Những thông tin như ngày sinh, giới tính, sốđiện thoại...
|
| 327 |
+
es a function →Output: Hi Alice`
|
| 328 |
+
|
| 329 |
+
|
| 330 |
+
2. **Stateful function** : Hàm có thểghi nhớtrạng thái bên trong. 1 `class Counter:`
|
| 331 |
+
|
| 332 |
+
|
| 333 |
+
2 `def __init__(self):`
|
| 334 |
+
|
| 335 |
+
|
| 336 |
+
3 `self.count = 0`
|
| 337 |
+
|
| 338 |
+
|
| 339 |
+
4
|
| 340 |
+
|
| 341 |
+
|
| 342 |
+
5 `def __call__(self):`
|
| 343 |
+
|
| 344 |
+
|
| 345 |
+
6 `self.count += 1`
|
| 346 |
+
|
| 347 |
+
|
| 348 |
+
7 `return self.count`
|
| 349 |
+
|
| 350 |
+
|
| 351 |
+
8
|
| 352 |
+
|
| 353 |
+
|
| 354 |
+
9 `counter = Counter()`
|
| 355 |
+
|
| 356 |
+
|
| 357 |
+
10
|
| 358 |
+
|
| 359 |
+
|
| 360 |
+
11 `print(counter())` `# 1`
|
| 361 |
+
|
| 362 |
+
12 `print(counter())` `# 2`
|
| 363 |
+
|
| 364 |
+
13 `print(counter())` `# 3`
|
| 365 |
+
|
| 366 |
+
|
| 367 |
+
Mỗi lần gọi `counter()` đều ghi nhớtrạng thái trước đó và cộng dồn lên, không giống như
|
| 368 |
+
các phương thức thông thường vốn không lưu trạng thái giữa các lần gọi. 3. **Decorator hoặc Callback handler** : (nâng cao cần tìm hiểu thêm). ## **Phần II: Các tính chất cơ bản trong Object-** **Oriented Programming**
|
| 369 |
+
|
| 370 |
+
### **5** **Delegation (Ủy quyền)**
|
| 371 |
+
|
| 372 |
+
|
| 373 |
+
Delegation (ủy quyền) trong lập trình hướng đối tượng là một kỹthuật trong đó một đối tượng
|
| 374 |
+
ủy thác trách nhiệm thực hiện một hành vi cụthểcho một đối tượng khác. Thay vì kếthừa trực
|
| 375 |
+
|
| 376 |
+
|
| 377 |
+
5
|
| 378 |
+
**AI VIETNAM** **aivietnam.edu.vn**
|
| 379 |
+
|
| 380 |
+
|
| 381 |
+
Trong Python, `__call__` là một **phương thức đặc biệt** (giống như `__init__`, `__str__`, v.v.)
|
| 382 |
+
được sửdụng khi một đối tượng cần hành xửgiống như một hàm. Nếu một lớp định nghĩa
|
| 383 |
+
`__call__`, thì các _instance_ của lớp đó có thểđược gọi như một hàm thực sự. Phương thức `__call__()` thường được dùng trong ba tình huống phổbiến:
|
| 384 |
+
|
| 385 |
+
|
| 386 |
+
1. **Function factory** : Tạo ra các đối tượng có thểxửlý logic như một hàm. 1 `class SayHi:`
|
| 387 |
+
|
| 388 |
+
2 `def __init__(self, name):`
|
| 389 |
+
|
| 390 |
+
|
| 391 |
+
3 `self.name = name`
|
| 392 |
+
|
| 393 |
+
|
| 394 |
+
4
|
| 395 |
+
|
| 396 |
+
|
| 397 |
+
5 `def hello(self):`
|
| 398 |
+
|
| 399 |
+
6 `print(f'Hello {self.name}')`
|
| 400 |
+
|
| 401 |
+
|
| 402 |
+
7
|
| 403 |
+
|
| 404 |
+
|
| 405 |
+
8 `def __call__(self, prefix):`
|
| 406 |
+
|
| 407 |
+
9 `print(f'{prefix} {self.name}')`
|
| 408 |
+
|
| 409 |
+
|
| 410 |
+
10
|
| 411 |
+
|
| 412 |
+
|
| 413 |
+
11 `obj = SayHi("Alice")`
|
| 414 |
+
|
| 415 |
+
12 `obj.hello()`
|
| 416 |
+
|
| 417 |
+
13 `obj("Hi")` `# __call__ make it becomes a function →Output: Hi Alice`
|
| 418 |
+
|
| 419 |
+
|
| 420 |
+
2. **Stateful function** : Hàm có thểghi nhớtrạng thái bên trong.
|
| 421 |
+
### **4.4** **Các lỗhổng được khai thác**
|
| 422 |
+
|
| 423 |
+
#### **4.4.1 Command injection trong tính năng chuẩn đoán** **ping**
|
| 424 |
+
|
| 425 |
+
Lỗhổng này có mã CVE là **CVE-2024-51186** [13]. Đây là lỗhổng trong
|
| 426 |
+
dịch vụ **ncc2** của thiết bịnày. Trong dịch vụ **ncc2** này, có một endpoint xử
|
| 427 |
+
lý CGI request là **ping.ccp** . Endpoint này cho phép chuẩn đoán các thiết
|
| 428 |
+
bịqua mạng bằng cách "ping"các thiết bịđó. Dưới đây là ảnh giao diện cho
|
| 429 |
+
phép người dùng tương tác với tính năng này.
|
| 430 |
+
|
| 431 |
+
|
| 432 |
+
18
|
| 433 |
+
w.theguardian.com/technology/2017/feb/28/cloudpets-data-breach-leaks-details-of-500000-children-and-adults/)
|
| 434 |
+
[cloudpets-data-breach-leaks-details-of-500000-children-and-adults/.](https://www.theguardian.com/technology/2017/feb/28/cloudpets-data-breach-leaks-details-of-500000-children-and-adults/)
|
| 435 |
+
|
| 436 |
+
|
| 437 |
+
33
|
| 438 |
+
# **Chương 2** **Các mối đe dọa vềbảo mật** **trong IoT**
|
| 439 |
+
|
| 440 |
+
Hệsinh thái IoT đã tạo ra một môi trường đe dọa đa tầng. Các mối đe dọa
|
| 441 |
+
vềmặt bảo mật trong IoT có thểđược được phân loại theo các tầng khác
|
| 442 |
+
nhau trong kiến trúc IoT, đồng thời các phương thức khai thác có thểcó các
|
| 443 |
+
hậu quảkhác nhau.
|
| 444 |
+
|
| 445 |
+
### **2.1** **Mối đe dọa tầng cảm biến**
|
| 446 |
+
|
| 447 |
+
#### **2.1.1 Khai thác thiết bịvật lý**
|
| 448 |
+
|
| 449 |
+
|
| 450 |
+
Nhiều nhà sản xuất thiết bịIoT thường đểlộchân UART/JTAG hoặc bật
|
| 451 |
+
chếđộconsole gỡlỗi ngay trên thiết bịthương mại. Khi có quyền truy cập vật
|
| 452 |
+
lý, kẻtấn công có thểtrích xuất dữliệu từbộnhớflash, trích xuất firmware,
|
| 453 |
+
chiếm quyền shell root hoặc thậm chí cài đặt firmware có chứa mã độc. [3]
|
| 454 |
+
|
| 455 |
+
#### **2.1.2 Tấn công side-channel**
|
| 456 |
+
|
| 457 |
+
|
| 458 |
+
Bằng cách theo dõi mức tiêu thụđiện năng hay bức xạđiện từcủa thiết bị
|
| 459 |
+
khi thực hiện các phép toán mã hóa và giải mã, người tấn công có thểchiết
|
| 460 |
+
xuất khóa bí mật dùng đểmã hóa/giải mã hoặc trộm cắp dữliệu nhạy cảm
|
| 461 |
+
bên trong. [4]
|
| 462 |
+
|
| 463 |
+
#### **2.1.3 Chỉnh sửa firmware**
|
| 464 |
+
|
| 465 |
+
|
| 466 |
+
Một người tấn công có thểlợi dụng việc thiếu cơ chếxác thực chặt chẽtrong
|
| 467 |
+
quá trình cập nhật firmware qua OTA (Over-The-Air). Họcó thểkhiến thiết
|
| 468 |
+
|
| 469 |
+
|
| 470 |
+
6
|
| 471 |
+
w.theguardian.com/technology/2017/feb/28/cloudpets-data-breach-leaks-details-of-500000-children-and-adults/)
|
| 472 |
+
[cloudpets-data-breach-leaks-details-of-500000-children-and-adults/.](https://www.theguardian.com/technology/2017/feb/28/cloudpets-data-breach-leaks-details-of-500000-children-and-adults/)
|
| 473 |
+
|
| 474 |
+
|
| 475 |
+
33
|
| 476 |
+
### **4.4** **Các lỗhổng được khai thác**
|
| 477 |
+
|
| 478 |
+
#### **4.4.1 Command injection trong tính năng chuẩn đoán** **ping**
|
| 479 |
+
|
| 480 |
+
Lỗhổng này có mã CVE là **CVE-2024-51186** [13]. Đây là lỗhổng trong
|
| 481 |
+
dịch vụ **ncc2** của thiết bịnày. Trong dịch vụ **ncc2** này, có một endpoint xử
|
| 482 |
+
lý CGI request là **ping.ccp** . Endpoint này cho phép chuẩn đoán các thiết
|
| 483 |
+
bịqua mạng bằng cách "ping"các thiết bịđó. Dưới đây là ảnh giao diện cho
|
| 484 |
+
phép người dùng tương tác với tính năng này.
|
| 485 |
+
|
| 486 |
+
|
| 487 |
+
18
|
| 488 |
+
### **Ví dụ với đống lớn nhất (max-heap)**
|
| 489 |
+
|
| 490 |
+
Sau buildHeap() Sau deleteMax() đầu tiên
|
| 491 |
+
### **Ví dụ về sắp xếp trộn (merge sort)**
|
| 492 |
+
|
| 493 |
+
1 24 26 15 13 2 27 38
|
| 494 |
+
|
| 495 |
+
|
| 496 |
+
1 24 26 15 13 2 27 38
|
| 497 |
+
|
| 498 |
+
|
| 499 |
+
1 24 26 15 13 2 27 38
|
| 500 |
+
|
| 501 |
+
|
| 502 |
+
1 24 26 15 13 2 27 38
|
| 503 |
+
|
| 504 |
+
|
| 505 |
+
1 24 15 26 2 13 27 38
|
| 506 |
+
|
| 507 |
+
|
| 508 |
+
1 15 24 26 2 13 27 38
|
| 509 |
+
|
| 510 |
+
|
| 511 |
+
1 2 13 15 24 26 27 38
|
| 512 |
+
## **Các thuật toán sắp xếp - phần 2**
|
| 513 |
+
|
| 514 |
+
|
| 515 |
+
Sắp xếp vun đống (heap sort)
|
| 516 |
+
|
| 517 |
+
Sắp xếp trộn (merge sort)
|
| 518 |
+
|
| 519 |
+
Sắp xếp nhanh (quick sort)
|
| 520 |
+
## **Ví dụ về trộn (merge)**
|
| 521 |
+
|
| 522 |
+
1 15 24 26 2 13 27 38
|
| 523 |
+
|
| 524 |
+
|1|15|24|26|
|
| 525 |
+
|---|---|---|---|
|
| 526 |
+
|||||
|
| 527 |
+
|
| 528 |
+
|
| 529 |
+
|2|13|27|38|
|
| 530 |
+
|---|---|---|---|
|
| 531 |
+
|||||
|
| 532 |
+
|
| 533 |
+
|
| 534 |
+
|
| 535 |
+
1 15 24 26 2 13 27 38 1
|
| 536 |
+
|
| 537 |
+
|1|15|24|26|
|
| 538 |
+
|---|---|---|---|
|
| 539 |
+
|||||
|
| 540 |
+
|
| 541 |
+
|
| 542 |
+
|2|13|27|38|
|
| 543 |
+
|---|---|---|---|
|
| 544 |
+
|||||
|
| 545 |
+
|
| 546 |
+
|
| 547 |
+
|1|Col2|Col3|Col4|Col5|Col6|Col7|Col8|
|
| 548 |
+
|---|---|---|---|---|---|---|---|
|
| 549 |
+
|||||||||
|
| 550 |
+
|
| 551 |
+
|
| 552 |
+
|
| 553 |
+
1 15 24 26 2 13 27 38 1 2
|
| 554 |
+
|
| 555 |
+
|1|15|24|26|
|
| 556 |
+
|---|---|---|---|
|
| 557 |
+
|||||
|
| 558 |
+
|
| 559 |
+
|
| 560 |
+
|2|13|27|38|
|
| 561 |
+
|---|---|---|---|
|
| 562 |
+
|||||
|
| 563 |
+
|
| 564 |
+
|
| 565 |
+
|1|2|Col3|Col4|Col5|Col6|Col7|Col8|
|
| 566 |
+
|---|---|---|---|---|---|---|---|
|
| 567 |
+
|||||||||
|
| 568 |
+
|
| 569 |
+
|
| 570 |
+
|
| 571 |
+
1 15 24 26 2 13 27 38 1 2 13
|
| 572 |
+
|
| 573 |
+
|
| 574 |
+
|
| 575 |
+
|1|15|24|26|
|
| 576 |
+
|---|---|---|---|
|
| 577 |
+
|||||
|
| 578 |
+
|
| 579 |
+
Có N bước
|
| 580 |
+
|
| 581 |
+
|
| 582 |
+
|2|13|27|38|
|
| 583 |
+
|---|---|---|---|
|
| 584 |
+
|||||
|
| 585 |
+
|
| 586 |
+
|
| 587 |
+
|1|2|13|Col4|Col5|Col6|Col7|Col8|
|
| 588 |
+
|---|---|---|---|---|---|---|---|
|
| 589 |
+
|||||||||
|
| 590 |
+
|
| 591 |
+
Mỗi bước có thể có một phép so sánh và có một phần tử được
|
| 592 |
+
|
| 593 |
+
chèn vào mảng thứ ba mỗi bước mất thời gian hằng
|
| 594 |
+
|
| 595 |
+
Tổng thời gian là O(N)
|
| 596 |
+
#### **Cài đặt sắp xếp trộn**
|
generator.py
CHANGED
|
@@ -1,11 +1,12 @@
|
|
| 1 |
import re
|
| 2 |
import random
|
|
|
|
| 3 |
import numpy as np
|
| 4 |
-
|
|
|
|
| 5 |
from sentence_transformers import SentenceTransformer
|
| 6 |
from uuid import uuid4
|
| 7 |
import pymupdf4llm
|
| 8 |
-
import pymupdf as fitz
|
| 9 |
|
| 10 |
try:
|
| 11 |
from qdrant_client import QdrantClient
|
|
@@ -28,19 +29,19 @@ try:
|
|
| 28 |
except Exception:
|
| 29 |
_HAS_FAISS = False
|
| 30 |
|
| 31 |
-
from utils import generate_mcqs_from_text, _post_chat, _safe_extract_json
|
| 32 |
|
| 33 |
class RAGMCQ:
|
| 34 |
def __init__(
|
| 35 |
self,
|
| 36 |
embedder_model: str = "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2",
|
| 37 |
-
|
| 38 |
-
qdrant_url: str =
|
| 39 |
-
qdrant_api_key: str =
|
| 40 |
qdrant_prefer_grpc: bool = False,
|
| 41 |
):
|
| 42 |
self.embedder = SentenceTransformer(embedder_model)
|
| 43 |
-
self.
|
| 44 |
self.embeddings = None # np.array of shape (N, D)
|
| 45 |
self.texts = [] # list of chunk texts
|
| 46 |
self.metadata = [] # list of dicts (page, chunk_id, char_range)
|
|
@@ -51,56 +52,61 @@ class RAGMCQ:
|
|
| 51 |
self.qdrant_url = qdrant_url
|
| 52 |
self.qdrant_api_key = qdrant_api_key
|
| 53 |
self.qdrant_prefer_grpc = qdrant_prefer_grpc
|
|
|
|
| 54 |
if qdrant_url:
|
| 55 |
self.connect_qdrant(qdrant_url, qdrant_api_key, qdrant_prefer_grpc)
|
| 56 |
|
| 57 |
def extract_pages(
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
|
| 86 |
def chunk_text(self, text: str, max_chars: int = 1200, overlap: int = 100) -> List[str]:
|
| 87 |
text = text.strip()
|
| 88 |
if not text:
|
| 89 |
return []
|
|
|
|
| 90 |
if len(text) <= max_chars:
|
| 91 |
return [text]
|
| 92 |
-
|
| 93 |
# split by sentence-like boundaries
|
| 94 |
sentences = re.split(r'(?<=[\.\?\!])\s+', text)
|
| 95 |
chunks = []
|
| 96 |
cur = ""
|
|
|
|
| 97 |
for s in sentences:
|
| 98 |
if len(cur) + len(s) + 1 <= max_chars:
|
| 99 |
cur += (" " if cur else "") + s
|
| 100 |
else:
|
| 101 |
if cur:
|
| 102 |
chunks.append(cur)
|
|
|
|
| 103 |
cur = (cur[-overlap:] + " " + s) if overlap > 0 else s
|
|
|
|
| 104 |
if cur:
|
| 105 |
chunks.append(cur)
|
| 106 |
|
|
@@ -112,10 +118,12 @@ class RAGMCQ:
|
|
| 112 |
else:
|
| 113 |
for i in range(0, len(c), max_chars):
|
| 114 |
final.append(c[i:i+max_chars])
|
|
|
|
| 115 |
return final
|
| 116 |
|
| 117 |
def build_index_from_pdf(self, pdf_path: str, max_chars: int = 1200):
|
| 118 |
pages = self.extract_pages(pdf_path)
|
|
|
|
| 119 |
self.texts = []
|
| 120 |
self.metadata = []
|
| 121 |
|
|
@@ -128,6 +136,8 @@ class RAGMCQ:
|
|
| 128 |
if not self.texts:
|
| 129 |
raise RuntimeError("No text extracted from PDF.")
|
| 130 |
|
|
|
|
|
|
|
| 131 |
# compute embeddings
|
| 132 |
emb = self.embedder.encode(self.texts, convert_to_numpy=True, show_progress_bar=True)
|
| 133 |
self.embeddings = emb.astype("float32")
|
|
@@ -188,7 +198,7 @@ class RAGMCQ:
|
|
| 188 |
# ask generator
|
| 189 |
try:
|
| 190 |
mcq_block = generate_mcqs_from_text(
|
| 191 |
-
chunk_text, n=to_gen, model=self.
|
| 192 |
)
|
| 193 |
except Exception as e:
|
| 194 |
# skip this chunk if generator fails
|
|
@@ -200,7 +210,7 @@ class RAGMCQ:
|
|
| 200 |
output[str(qcount)] = mcq_block[item]
|
| 201 |
if qcount >= n_questions:
|
| 202 |
return output
|
| 203 |
-
|
| 204 |
return output
|
| 205 |
|
| 206 |
elif mode == "rag":
|
|
@@ -215,13 +225,12 @@ class RAGMCQ:
|
|
| 215 |
# create a seed query: pick a random chunk, pick a sentence from it
|
| 216 |
seed_idx = random.randrange(len(self.texts))
|
| 217 |
chunk = self.texts[seed_idx]
|
|
|
|
|
|
|
|
|
|
|
|
|
| 218 |
sents = re.split(r'(?<=[\.\?\!])\s+', chunk)
|
| 219 |
-
|
| 220 |
-
if candidate:
|
| 221 |
-
seed_sent = random.choice(candidate)
|
| 222 |
-
else:
|
| 223 |
-
stripped = chunk.strip()
|
| 224 |
-
seed_sent = (stripped[:200] if stripped else "[no text available]")
|
| 225 |
query = f"Create questions about: {seed_sent}"
|
| 226 |
|
| 227 |
# retrieve top_k chunks
|
|
@@ -232,12 +241,15 @@ class RAGMCQ:
|
|
| 232 |
context_parts.append(f"[page {md['page']}] {self.texts[ridx]}")
|
| 233 |
context = "\n\n".join(context_parts)
|
| 234 |
|
|
|
|
|
|
|
| 235 |
# call generator for 1 question (or small batch) with the retrieved context
|
| 236 |
try:
|
| 237 |
# request 1 question at a time to keep diversity
|
| 238 |
mcq_block = generate_mcqs_from_text(
|
| 239 |
-
context, n=1, model=self.
|
| 240 |
)
|
|
|
|
| 241 |
except Exception as e:
|
| 242 |
print(f"Generator failed during RAG attempt {attempts}: {e}")
|
| 243 |
continue
|
|
@@ -248,7 +260,7 @@ class RAGMCQ:
|
|
| 248 |
output[str(qcount)] = mcq_block[item]
|
| 249 |
if qcount >= n_questions:
|
| 250 |
return output
|
| 251 |
-
|
| 252 |
return output
|
| 253 |
else:
|
| 254 |
raise ValueError("mode must be 'per_page' or 'rag'.")
|
|
@@ -287,7 +299,7 @@ class RAGMCQ:
|
|
| 287 |
system = {
|
| 288 |
"role": "system",
|
| 289 |
"content": (
|
| 290 |
-
"Bạn là một trợ lý đánh giá tính thực chứng của câu hỏi trắc nghiệm dựa trên đoạn văn được cung cấp. "
|
| 291 |
"Hãy trả lời DUY NHẤT bằng JSON hợp lệ (không có văn bản khác) theo schema:\n\n"
|
| 292 |
"{\n"
|
| 293 |
' "supported": true/false, # câu trả lời đúng có được nội dung chứng thực không\n'
|
|
@@ -309,7 +321,7 @@ class RAGMCQ:
|
|
| 309 |
)
|
| 310 |
}
|
| 311 |
|
| 312 |
-
raw = _post_chat([system, user], model=self.
|
| 313 |
|
| 314 |
# parse JSON object in response
|
| 315 |
try:
|
|
@@ -403,6 +415,7 @@ class RAGMCQ:
|
|
| 403 |
|
| 404 |
# extract pages and chunks (re-using your existing helpers)
|
| 405 |
pages = self.extract_pages(pdf_path)
|
|
|
|
| 406 |
all_chunks = []
|
| 407 |
all_meta = []
|
| 408 |
for p_idx, page_text in enumerate(pages, start=1):
|
|
@@ -412,7 +425,7 @@ class RAGMCQ:
|
|
| 412 |
all_meta.append({"page": p_idx, "chunk_id": cid, "length": len(ch)})
|
| 413 |
|
| 414 |
if not all_chunks:
|
| 415 |
-
raise RuntimeError("No
|
| 416 |
|
| 417 |
# ensure collection exists
|
| 418 |
self._ensure_collection(collection)
|
|
@@ -646,7 +659,7 @@ class RAGMCQ:
|
|
| 646 |
continue
|
| 647 |
to_gen = questions_per_chunk
|
| 648 |
try:
|
| 649 |
-
mcq_block = generate_mcqs_from_text(txt, n=to_gen, model=self.
|
| 650 |
except Exception as e:
|
| 651 |
print(f"Generator failed on chunk (index {i}): {e}")
|
| 652 |
continue
|
|
@@ -662,19 +675,19 @@ class RAGMCQ:
|
|
| 662 |
max_attempts = n_questions * 4
|
| 663 |
while qcount < n_questions and attempts < max_attempts:
|
| 664 |
attempts += 1
|
| 665 |
-
#
|
| 666 |
-
seed_idx = random.randrange(len(texts))
|
| 667 |
-
chunk = texts[seed_idx]
|
| 668 |
sents = re.split(r'(?<=[\.\?\!])\s+', chunk)
|
| 669 |
-
|
| 670 |
-
|
| 671 |
-
|
| 672 |
-
|
| 673 |
-
|
| 674 |
-
|
| 675 |
-
seed_sent = chunk[:200]
|
| 676 |
query = f"Create questions about: {seed_sent}"
|
| 677 |
|
|
|
|
| 678 |
# retrieve top_k chunks from the same file (restricted by filename filter)
|
| 679 |
retrieved = self._retrieve_qdrant(query=query, collection=collection, filename=filename, top_k=top_k)
|
| 680 |
context_parts = []
|
|
@@ -686,7 +699,7 @@ class RAGMCQ:
|
|
| 686 |
context = "\n\n".join(context_parts)
|
| 687 |
|
| 688 |
try:
|
| 689 |
-
mcq_block = generate_mcqs_from_text(context, n=1, model=self.
|
| 690 |
except Exception as e:
|
| 691 |
print(f"Generator failed during RAG attempt {attempts}: {e}")
|
| 692 |
continue
|
|
|
|
| 1 |
import re
|
| 2 |
import random
|
| 3 |
+
import fitz
|
| 4 |
import numpy as np
|
| 5 |
+
import os
|
| 6 |
+
from typing import List, Optional, Tuple, Dict, Any
|
| 7 |
from sentence_transformers import SentenceTransformer
|
| 8 |
from uuid import uuid4
|
| 9 |
import pymupdf4llm
|
|
|
|
| 10 |
|
| 11 |
try:
|
| 12 |
from qdrant_client import QdrantClient
|
|
|
|
| 29 |
except Exception:
|
| 30 |
_HAS_FAISS = False
|
| 31 |
|
| 32 |
+
from utils import generate_mcqs_from_text, _post_chat, _safe_extract_json, save_to_local
|
| 33 |
|
| 34 |
class RAGMCQ:
|
| 35 |
def __init__(
|
| 36 |
self,
|
| 37 |
embedder_model: str = "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2",
|
| 38 |
+
generation_model: str = "gpt-oss-120b",
|
| 39 |
+
qdrant_url: str = os.environ.get('QDRANT_URL') or "",
|
| 40 |
+
qdrant_api_key: str = os.environ.get('QDRANT_API_KEY') or "",
|
| 41 |
qdrant_prefer_grpc: bool = False,
|
| 42 |
):
|
| 43 |
self.embedder = SentenceTransformer(embedder_model)
|
| 44 |
+
self.generation_model = generation_model
|
| 45 |
self.embeddings = None # np.array of shape (N, D)
|
| 46 |
self.texts = [] # list of chunk texts
|
| 47 |
self.metadata = [] # list of dicts (page, chunk_id, char_range)
|
|
|
|
| 52 |
self.qdrant_url = qdrant_url
|
| 53 |
self.qdrant_api_key = qdrant_api_key
|
| 54 |
self.qdrant_prefer_grpc = qdrant_prefer_grpc
|
| 55 |
+
|
| 56 |
if qdrant_url:
|
| 57 |
self.connect_qdrant(qdrant_url, qdrant_api_key, qdrant_prefer_grpc)
|
| 58 |
|
| 59 |
def extract_pages(
|
| 60 |
+
self,
|
| 61 |
+
pdf_path: str,
|
| 62 |
+
*,
|
| 63 |
+
pages: Optional[List[int]] = None,
|
| 64 |
+
ignore_images: bool = False,
|
| 65 |
+
dpi: int = 150
|
| 66 |
+
) -> List[str]:
|
| 67 |
+
doc = fitz.open(pdf_path)
|
| 68 |
+
try:
|
| 69 |
+
# request page-wise output (page_chunks=True -> list[dict] per page)
|
| 70 |
+
page_dicts = pymupdf4llm.to_markdown(
|
| 71 |
+
doc,
|
| 72 |
+
pages=pages,
|
| 73 |
+
ignore_images=ignore_images,
|
| 74 |
+
dpi=dpi,
|
| 75 |
+
page_chunks=True,
|
| 76 |
+
)
|
| 77 |
|
| 78 |
+
# to_markdown(..., page_chunks=True) returns a list of dicts, each has key "text" (markdown)
|
| 79 |
+
pages_md: List[str] = []
|
| 80 |
+
for p in page_dicts:
|
| 81 |
+
txt = p.get("text", "") or ""
|
| 82 |
+
pages_md.append(txt.strip())
|
| 83 |
|
| 84 |
+
return pages_md
|
| 85 |
+
finally:
|
| 86 |
+
doc.close()
|
| 87 |
|
| 88 |
def chunk_text(self, text: str, max_chars: int = 1200, overlap: int = 100) -> List[str]:
|
| 89 |
text = text.strip()
|
| 90 |
if not text:
|
| 91 |
return []
|
| 92 |
+
|
| 93 |
if len(text) <= max_chars:
|
| 94 |
return [text]
|
| 95 |
+
|
| 96 |
# split by sentence-like boundaries
|
| 97 |
sentences = re.split(r'(?<=[\.\?\!])\s+', text)
|
| 98 |
chunks = []
|
| 99 |
cur = ""
|
| 100 |
+
|
| 101 |
for s in sentences:
|
| 102 |
if len(cur) + len(s) + 1 <= max_chars:
|
| 103 |
cur += (" " if cur else "") + s
|
| 104 |
else:
|
| 105 |
if cur:
|
| 106 |
chunks.append(cur)
|
| 107 |
+
|
| 108 |
cur = (cur[-overlap:] + " " + s) if overlap > 0 else s
|
| 109 |
+
|
| 110 |
if cur:
|
| 111 |
chunks.append(cur)
|
| 112 |
|
|
|
|
| 118 |
else:
|
| 119 |
for i in range(0, len(c), max_chars):
|
| 120 |
final.append(c[i:i+max_chars])
|
| 121 |
+
|
| 122 |
return final
|
| 123 |
|
| 124 |
def build_index_from_pdf(self, pdf_path: str, max_chars: int = 1200):
|
| 125 |
pages = self.extract_pages(pdf_path)
|
| 126 |
+
|
| 127 |
self.texts = []
|
| 128 |
self.metadata = []
|
| 129 |
|
|
|
|
| 136 |
if not self.texts:
|
| 137 |
raise RuntimeError("No text extracted from PDF.")
|
| 138 |
|
| 139 |
+
save_to_local('test/text_chunks.md', content=self.texts)
|
| 140 |
+
|
| 141 |
# compute embeddings
|
| 142 |
emb = self.embedder.encode(self.texts, convert_to_numpy=True, show_progress_bar=True)
|
| 143 |
self.embeddings = emb.astype("float32")
|
|
|
|
| 198 |
# ask generator
|
| 199 |
try:
|
| 200 |
mcq_block = generate_mcqs_from_text(
|
| 201 |
+
chunk_text, n=to_gen, model=self.generation_model, temperature=temperature
|
| 202 |
)
|
| 203 |
except Exception as e:
|
| 204 |
# skip this chunk if generator fails
|
|
|
|
| 210 |
output[str(qcount)] = mcq_block[item]
|
| 211 |
if qcount >= n_questions:
|
| 212 |
return output
|
| 213 |
+
|
| 214 |
return output
|
| 215 |
|
| 216 |
elif mode == "rag":
|
|
|
|
| 225 |
# create a seed query: pick a random chunk, pick a sentence from it
|
| 226 |
seed_idx = random.randrange(len(self.texts))
|
| 227 |
chunk = self.texts[seed_idx]
|
| 228 |
+
|
| 229 |
+
#? Investigate Chunking Strategy
|
| 230 |
+
with open("chunks.txt", "a", encoding="utf-8") as f: f.write(chunk + "\n")
|
| 231 |
+
|
| 232 |
sents = re.split(r'(?<=[\.\?\!])\s+', chunk)
|
| 233 |
+
seed_sent = random.choice([s for s in sents if len(s.strip()) > 20]) if sents else chunk[:200]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 234 |
query = f"Create questions about: {seed_sent}"
|
| 235 |
|
| 236 |
# retrieve top_k chunks
|
|
|
|
| 241 |
context_parts.append(f"[page {md['page']}] {self.texts[ridx]}")
|
| 242 |
context = "\n\n".join(context_parts)
|
| 243 |
|
| 244 |
+
save_to_local('test/context.md', content=context)
|
| 245 |
+
|
| 246 |
# call generator for 1 question (or small batch) with the retrieved context
|
| 247 |
try:
|
| 248 |
# request 1 question at a time to keep diversity
|
| 249 |
mcq_block = generate_mcqs_from_text(
|
| 250 |
+
context, n=1, model=self.generation_model, temperature=temperature
|
| 251 |
)
|
| 252 |
+
|
| 253 |
except Exception as e:
|
| 254 |
print(f"Generator failed during RAG attempt {attempts}: {e}")
|
| 255 |
continue
|
|
|
|
| 260 |
output[str(qcount)] = mcq_block[item]
|
| 261 |
if qcount >= n_questions:
|
| 262 |
return output
|
| 263 |
+
|
| 264 |
return output
|
| 265 |
else:
|
| 266 |
raise ValueError("mode must be 'per_page' or 'rag'.")
|
|
|
|
| 299 |
system = {
|
| 300 |
"role": "system",
|
| 301 |
"content": (
|
| 302 |
+
"Bạn là một trợ lý đánh giá tính thực chứng của câu hỏi trắc nghiệm dựa trên đoạn văn được cung cấp. Luôn trả lời bằng Tiếng Việt"
|
| 303 |
"Hãy trả lời DUY NHẤT bằng JSON hợp lệ (không có văn bản khác) theo schema:\n\n"
|
| 304 |
"{\n"
|
| 305 |
' "supported": true/false, # câu trả lời đúng có được nội dung chứng thực không\n'
|
|
|
|
| 321 |
)
|
| 322 |
}
|
| 323 |
|
| 324 |
+
raw = _post_chat([system, user], model=self.generation_model, temperature=model_verification_temperature)
|
| 325 |
|
| 326 |
# parse JSON object in response
|
| 327 |
try:
|
|
|
|
| 415 |
|
| 416 |
# extract pages and chunks (re-using your existing helpers)
|
| 417 |
pages = self.extract_pages(pdf_path)
|
| 418 |
+
|
| 419 |
all_chunks = []
|
| 420 |
all_meta = []
|
| 421 |
for p_idx, page_text in enumerate(pages, start=1):
|
|
|
|
| 425 |
all_meta.append({"page": p_idx, "chunk_id": cid, "length": len(ch)})
|
| 426 |
|
| 427 |
if not all_chunks:
|
| 428 |
+
raise RuntimeError("No tSext extracted from PDF.")
|
| 429 |
|
| 430 |
# ensure collection exists
|
| 431 |
self._ensure_collection(collection)
|
|
|
|
| 659 |
continue
|
| 660 |
to_gen = questions_per_chunk
|
| 661 |
try:
|
| 662 |
+
mcq_block = generate_mcqs_from_text(txt, n=to_gen, model=self.generation_model, temperature=temperature)
|
| 663 |
except Exception as e:
|
| 664 |
print(f"Generator failed on chunk (index {i}): {e}")
|
| 665 |
continue
|
|
|
|
| 675 |
max_attempts = n_questions * 4
|
| 676 |
while qcount < n_questions and attempts < max_attempts:
|
| 677 |
attempts += 1
|
| 678 |
+
# create a seed query: pick a random chunk, pick a sentence from it
|
| 679 |
+
seed_idx = random.randrange(len(self.texts))
|
| 680 |
+
chunk = self.texts[seed_idx]
|
| 681 |
sents = re.split(r'(?<=[\.\?\!])\s+', chunk)
|
| 682 |
+
candidate = [s for s in sents if len(s.strip()) > 20]
|
| 683 |
+
if candidate:
|
| 684 |
+
seed_sent = random.choice(candidate)
|
| 685 |
+
else:
|
| 686 |
+
stripped = chunk.strip()
|
| 687 |
+
seed_sent = (stripped[:200] if stripped else "[no text available]")
|
|
|
|
| 688 |
query = f"Create questions about: {seed_sent}"
|
| 689 |
|
| 690 |
+
|
| 691 |
# retrieve top_k chunks from the same file (restricted by filename filter)
|
| 692 |
retrieved = self._retrieve_qdrant(query=query, collection=collection, filename=filename, top_k=top_k)
|
| 693 |
context_parts = []
|
|
|
|
| 699 |
context = "\n\n".join(context_parts)
|
| 700 |
|
| 701 |
try:
|
| 702 |
+
mcq_block = generate_mcqs_from_text(context, n=1, model=self.generation_model, temperature=temperature)
|
| 703 |
except Exception as e:
|
| 704 |
print(f"Generator failed during RAG attempt {attempts}: {e}")
|
| 705 |
continue
|
requirements.txt
CHANGED
|
@@ -1,8 +1,8 @@
|
|
| 1 |
boto3
|
| 2 |
-
pdfplumber
|
| 3 |
faiss-cpu
|
| 4 |
sentence-transformers
|
| 5 |
fastapi[standard]
|
| 6 |
uvicorn[standard]
|
| 7 |
qdrant-client
|
| 8 |
pymupdf4llm
|
|
|
|
|
|
| 1 |
boto3
|
|
|
|
| 2 |
faiss-cpu
|
| 3 |
sentence-transformers
|
| 4 |
fastapi[standard]
|
| 5 |
uvicorn[standard]
|
| 6 |
qdrant-client
|
| 7 |
pymupdf4llm
|
| 8 |
+
uuid
|
test/DeepLearning_mcq_output.json
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"mcqs": {
|
| 3 |
+
"1": {
|
| 4 |
+
"câu hỏi": "Theo nội dung trên, điểm khác biệt chính của kiến trúc Transformer so với các mô hình trước đó là gì?",
|
| 5 |
+
"lựa chọn": {
|
| 6 |
+
"a": "Sử dụng mạng hồi tiếp (recurrent) để mô hình hoá phụ thuộc dài hạn",
|
| 7 |
+
"b": "Dựa hoàn toàn vào cơ chế attention mà không có bất kỳ thành phần hồi tiếp nào",
|
| 8 |
+
"c": "Áp dụng các lớp convolution để tính toán các biểu diễn ẩn",
|
| 9 |
+
"d": "Chỉ sử dụng các lớp feed‑forward điểm‑điểm mà không có attention"
|
| 10 |
+
},
|
| 11 |
+
"đáp án": "Dựa hoàn toàn vào cơ chế attention mà không có bất kỳ thành phần hồi tiếp nào"
|
| 12 |
+
},
|
| 13 |
+
"2": {
|
| 14 |
+
"câu hỏi": "Trong quá trình huấn luyện các mô hình được mô tả, thuật toán tối ưu nào đã được sử dụng?",
|
| 15 |
+
"lựa chọn": {
|
| 16 |
+
"a": "Adam optimizer",
|
| 17 |
+
"b": "Stochastic Gradient Descent (SGD)",
|
| 18 |
+
"c": "RMSprop",
|
| 19 |
+
"d": "Adagrad"
|
| 20 |
+
},
|
| 21 |
+
"đáp án": "Adam optimizer"
|
| 22 |
+
},
|
| 23 |
+
"3": {
|
| 24 |
+
"câu hỏi": "Theo Bảng 3, mô hình Transformer cơ bản (base) đạt điểm BLEU bao nhiêu trên tập phát triển English‑to‑German (newstest2013)?",
|
| 25 |
+
"lựa chọn": {
|
| 26 |
+
"a": "25.8",
|
| 27 |
+
"b": "24.9",
|
| 28 |
+
"c": "26.4",
|
| 29 |
+
"d": "23.7"
|
| 30 |
+
},
|
| 31 |
+
"đáp án": "25.8"
|
| 32 |
+
},
|
| 33 |
+
"4": {
|
| 34 |
+
"câu hỏi": "Theo mô tả trong tài liệu, số bước warmup (warmup steps) được sử dụng trong quá trình huấn luyện là bao nhiêu?",
|
| 35 |
+
"lựa chọn": {
|
| 36 |
+
"a": "2000",
|
| 37 |
+
"b": "4000",
|
| 38 |
+
"c": "8000",
|
| 39 |
+
"d": "10000"
|
| 40 |
+
},
|
| 41 |
+
"đáp án": "4000"
|
| 42 |
+
},
|
| 43 |
+
"5": {
|
| 44 |
+
"câu hỏi": "Theo nội dung, mô hình Transformer (big) đạt được điểm BLEU bao nhiêu trên nhiệm vụ dịch tiếng Anh‑tiếng Đức WMT 2014?",
|
| 45 |
+
"lựa chọn": {
|
| 46 |
+
"a": "28.4",
|
| 47 |
+
"b": "30.0",
|
| 48 |
+
"c": "26.5",
|
| 49 |
+
"d": "27.0"
|
| 50 |
+
},
|
| 51 |
+
"đáp án": "28.4"
|
| 52 |
+
}
|
| 53 |
+
},
|
| 54 |
+
"validation": {
|
| 55 |
+
"1": {
|
| 56 |
+
"supported_by_embeddings": true,
|
| 57 |
+
"max_similarity": 0.7559994459152222,
|
| 58 |
+
"evidence": [
|
| 59 |
+
{
|
| 60 |
+
"idx": 9,
|
| 61 |
+
"page": 2,
|
| 62 |
+
"score": 0.7559994459152222,
|
| 63 |
+
"text": "To the best of our knowledge, however, the Transformer is the first transduction model relying\nentirely on self-attention to compute representations of its input and output without using sequencealigned RNNs or convolution. In the following sections, we will describe the Transformer, motivate\nself-attention and discuss its advantages over models such as [17, 18] and [9]. **3** **Model Architecture**\n\n\nMost competitive neural sequence transduction models have an encoder-decoder structure [ 5, 2, 35 ]. Here, the encoder maps an input sequence of symbol representations ( _x_ 1 _, ..., x_ _n_ ) to a sequence\nof continuous representations **z** = ( _z_ 1 _, ..., z_ _n_ ) . Given **z**, the decoder then generates an output\nsequence ( _y_ 1 _, ..., y_ _m_ ) of symbols one element at a time. At each step the model is auto-regressive\n\n[10], consuming the previously generated symbols as additional input when generating the next. 2"
|
| 64 |
+
},
|
| 65 |
+
{
|
| 66 |
+
"idx": 5,
|
| 67 |
+
"page": 3,
|
| 68 |
+
"score": 0.6882933974266052,
|
| 69 |
+
"text": "Figure 1: The Transformer - model architecture.\n\n\nThe Transformer follows this overall architecture using stacked self-attention and point-wise, fully\nconnected layers for both the encoder and decoder, shown in the left and right halves of Figure 1,\nrespectively.\n\n\n**3.1** **Encoder and Decoder Stacks**\n\nthe two sub-layers, followed by layer normalization [ 1 ]. That is, the output of each sub-layer is\nLayerNorm( _x_ + Sublayer( _x_ )), where Sublayer( _x_ ) is the function implemented by the sub-layer\nitself. To facilitate these residual connections, all sub-layers in the model, as well as the embedding\nlayers, produce outputs of dimension _d_ model = 512.\n\nmasking, combined with fact that the output embeddings are offset by one position, ensures that the\npredictions for position _i_ can depend only on the known outputs at positions less than _i_ .\n\n\n**3.2** **Attention**\n\n\n3"
|
| 70 |
+
},
|
| 71 |
+
{
|
| 72 |
+
"idx": 11,
|
| 73 |
+
"page": 10,
|
| 74 |
+
"score": 0.6689025163650513,
|
| 75 |
+
"text": "We\nplan to extend the Transformer to problems involving input and output modalities other than text and\nto investigate local, restricted attention mechanisms to efficiently handle large inputs and outputs\nsuch as images, audio and video. Making generation less sequential is another research goals of ours. The code we used to train and evaluate our models is available at `[https://github.com/](https://github.com/tensorflow/tensor2tensor)`\n`[tensorflow/tensor2tensor](https://github.com/tensorflow/tensor2tensor)` . **Acknowledgements** We are grateful to Nal Kalchbrenner and Stephan Gouws for their fruitful\ncomments, corrections and inspiration. **References**\n\n\n[1] Jimmy Lei Ba, Jamie Ryan Kiros, and Geoffrey E Hinton. Layer normalization. _arXiv preprint_\n_[arXiv:1607.06450](http://arxiv.org/abs/1607.06450)_, 2016. [2] Dzmitry Bahdanau, Kyunghyun Cho, and Yoshua Bengio. Neural machine translation by jointly\nlearning to align and translate. _CoRR_, abs/1409.0473, 2014. [3] Denny Britz, A..."
|
| 76 |
+
}
|
| 77 |
+
],
|
| 78 |
+
"model_verdict": {
|
| 79 |
+
"supported": true,
|
| 80 |
+
"confidence": 0.99,
|
| 81 |
+
"evidence": "the Transformer is the first transduction model relying entirely on self-attention ... without using sequence‑aligned RNNs or convolution.",
|
| 82 |
+
"reason": "Context explicitly states Transformer relies fully on attention and has no recurrent components."
|
| 83 |
+
}
|
| 84 |
+
},
|
| 85 |
+
"2": {
|
| 86 |
+
"supported_by_embeddings": true,
|
| 87 |
+
"max_similarity": 0.6170728206634521,
|
| 88 |
+
"evidence": [
|
| 89 |
+
{
|
| 90 |
+
"idx": 33,
|
| 91 |
+
"page": 10,
|
| 92 |
+
"score": 0.6170728206634521,
|
| 93 |
+
"text": "Our results in Table 4 show that despite the lack of task-specific tuning our model performs surprisingly well, yielding better results than all previously reported models with the exception of the\nRecurrent Neural Network Grammar [8]. In contrast to RNN sequence-to-sequence models [ 37 ], the Transformer outperforms the BerkeleyParser [29] even when training only on the WSJ training set of 40K sentences. **7** **Conclusion**\n\n\nIn this work, we presented the Transformer, the first sequence transduction model based entirely on\nattention, replacing the recurrent layers most commonly used in encoder-decoder architectures with\nmulti-headed self-attention. For translation tasks, the Transformer can be trained significantly faster than architectures based\non recurrent or convolutional layers. On both WMT 2014 English-to-German and WMT 2014\nEnglish-to-French translation tasks, we achieve a new state of the art. In the former task our best\nmodel outperforms even all previously reported ensembl..."
|
| 94 |
+
},
|
| 95 |
+
{
|
| 96 |
+
"idx": 3,
|
| 97 |
+
"page": 9,
|
| 98 |
+
"score": 0.5712530016899109,
|
| 99 |
+
"text": "This task presents specific challenges: the output is subject to strong structural\nconstraints and is significantly longer than the input. Furthermore, RNN sequence-to-sequence\nmodels have not been able to attain state-of-the-art results in small-data regimes [37]. We trained a 4-layer transformer with _d_ _model_ = 1024 on the Wall Street Journal (WSJ) portion of the\nPenn Treebank [ 25 ], about 40K training sentences. We also trained it in a semi-supervised setting,\nusing the larger high-confidence and BerkleyParser corpora from with approximately 17M sentences\n\n[ 37 ]. We used a vocabulary of 16K tokens for the WSJ only setting and a vocabulary of 32K tokens\nfor the semi-supervised setting. We performed only a small number of experiments to select the dropout, both attention and residual\n(section 5.4), learning rates and beam size on the Section 22 development set, all other parameters\nremained unchanged from the English-to-German base translation model. During inference, we\n\n\n9"
|
| 100 |
+
},
|
| 101 |
+
{
|
| 102 |
+
"idx": 10,
|
| 103 |
+
"page": 8,
|
| 104 |
+
"score": 0.5459271669387817,
|
| 105 |
+
"text": "**Label Smoothing** During training, we employed label smoothing of value _ϵ_ _ls_ = 0 _._ 1 [ 36 ]. This\nhurts perplexity, as the model learns to be more unsure, but improves accuracy and BLEU score. **6** **Results**\n\n\n**6.1** **Machine Translation**\n\n\nOn the WMT 2014 English-to-German translation task, the big transformer model (Transformer (big)\nin Table 2) outperforms the best previously reported models (including ensembles) by more than 2 _._ 0\nBLEU, establishing a new state-of-the-art BLEU score of 28 _._ 4 . The configuration of this model is\nlisted in the bottom line of Table 3. Training took 3 _._ 5 days on 8 P100 GPUs. Even our base model\nsurpasses all previously published models and ensembles, at a fraction of the training cost of any of\nthe competitive models. On the WMT 2014 English-to-French translation task, our big model achieves a BLEU score of 41 _._ 0,\noutperforming all of the previously published single models, at less than 1 _/_ 4 the training cost of the\nprevious..."
|
| 106 |
+
}
|
| 107 |
+
],
|
| 108 |
+
"model_verdict": {
|
| 109 |
+
"supported": false,
|
| 110 |
+
"confidence": 0.99,
|
| 111 |
+
"evidence": "",
|
| 112 |
+
"reason": "Trong đoạn văn cung cấp không có thông tin nào đề cập đến thuật toán tối ưu được sử dụng, vì vậy không thể chứng thực đáp án 'Adam optimizer'."
|
| 113 |
+
}
|
| 114 |
+
},
|
| 115 |
+
"3": {
|
| 116 |
+
"supported_by_embeddings": true,
|
| 117 |
+
"max_similarity": 0.7403339743614197,
|
| 118 |
+
"evidence": [
|
| 119 |
+
{
|
| 120 |
+
"idx": 24,
|
| 121 |
+
"page": 8,
|
| 122 |
+
"score": 0.7403339743614197,
|
| 123 |
+
"text": "Table 2: The Transformer achieves better BLEU scores than previous state-of-the-art models on the\nEnglish-to-German and English-to-French newstest2014 tests at a fraction of the training cost. BLEU Training Cost (FLOPs)\nModel\n\nEN-DE EN-FR EN-DE EN-FR\nByteNet [18] 23.75\nDeep-Att + PosUnk [39] 39.2 1 _._ 0 _·_ 10 [20]\n\nGNMT + RL [38] 24.6 39.92 2 _._ 3 _·_ 10 [19] 1 _._ 4 _·_ 10 [20]\n\nConvS2S [9] 25.16 40.46 9 _._ 6 _·_ 10 [18] 1 _._ 5 _·_ 10 [20]\n\nMoE [32] 26.03 40.56 2 _._ 0 _·_ 10 [19] 1 _._ 2 _·_ 10 [20]\n\nDeep-Att + PosUnk Ensemble [39] 40.4 8 _._ 0 _·_ 10 [20]\n\nGNMT + RL Ensemble [38] 26.30 41.16 1 _._ 8 _·_ 10 [20] 1 _._ 1 _·_ 10 [21]\n\nConvS2S Ensemble [9] 26.36 **41.29** 7 _._ 7 _·_ 10 [19] 1 _._ 2 _·_ 10 [21]\n\nTransformer (base model) 27.3 38.1 **3** _**.**_ **3** _**·**_ **10** **[18]**\n\nTransformer (big) **28.4** **41.8** 2 _._ 3 _·_ 10 [19]\n\n\n**Residual Dropout** We apply dropout [ 33 ] to the output of each sub-layer, before it is added to the\nsub-layer input and normalized. ..."
|
| 124 |
+
},
|
| 125 |
+
{
|
| 126 |
+
"idx": 1,
|
| 127 |
+
"page": 9,
|
| 128 |
+
"score": 0.6753625273704529,
|
| 129 |
+
"text": "Table 3: Variations on the Transformer architecture. Unlisted values are identical to those of the base\nmodel. All metrics are on the English-to-German translation development set, newstest2013. Listed\nperplexities are per-wordpiece, according to our byte-pair encoding, and should not be compared to\nper-word perplexities. |Col1|train<br>N d d h d d P ϵ<br>model ff k v drop ls steps|PPL BLEU params<br>(dev) (dev) ×106|\n|---|---|---|\n|base|6<br>512<br>2048<br>8<br>64<br>64<br>0.1<br>0.1<br>100K|4.92<br>25.8<br>65|\n|(A)|1<br>512<br>512<br>4<br>128<br>128<br>16<br>32<br>32<br>32<br>16<br>16|5.29<br>24.9<br>5.00<br>25.5<br>4.91<br>25.8<br>5.01<br>25.4|\n|(B)|16<br>32|5.16<br>25.1<br>58<br>5.01<br>25.4<br>60|\n|(C)|2<br>4<br>8<br>256<br>32<br>32<br>1024<br>128<br>128<br>1024<br>4096|6.11<br>23.7<br>36<br>5.19<br>25.3<br>50<br>4.88<br>25.5<br>80<br>5.75<br>24.5<br>28<br>4.66<br>26.0<br>168<br>5.12<br>25.4<br>53<br>4.75<br>26.2<br>90|\n|(D)|0.0<br>0.2<br>0.0<br>0.2|5.77<br>24.6<br>4.95<br>25.5<br..."
|
| 130 |
+
},
|
| 131 |
+
{
|
| 132 |
+
"idx": 9,
|
| 133 |
+
"page": 2,
|
| 134 |
+
"score": 0.5718259811401367,
|
| 135 |
+
"text": "To the best of our knowledge, however, the Transformer is the first transduction model relying\nentirely on self-attention to compute representations of its input and output without using sequencealigned RNNs or convolution. In the following sections, we will describe the Transformer, motivate\nself-attention and discuss its advantages over models such as [17, 18] and [9]. **3** **Model Architecture**\n\n\nMost competitive neural sequence transduction models have an encoder-decoder structure [ 5, 2, 35 ]. Here, the encoder maps an input sequence of symbol representations ( _x_ 1 _, ..., x_ _n_ ) to a sequence\nof continuous representations **z** = ( _z_ 1 _, ..., z_ _n_ ) . Given **z**, the decoder then generates an output\nsequence ( _y_ 1 _, ..., y_ _m_ ) of symbols one element at a time. At each step the model is auto-regressive\n\n[10], consuming the previously generated symbols as additional input when generating the next. 2"
|
| 136 |
+
}
|
| 137 |
+
],
|
| 138 |
+
"model_verdict": {
|
| 139 |
+
"supported": true,
|
| 140 |
+
"confidence": 0.99,
|
| 141 |
+
"evidence": "base|6 512 2048 8 64 64 0.1 0.1 100K|4.92 25.8 65",
|
| 142 |
+
"reason": "Bảng 3 liệt kê mô hình Transformer (base) với BLEU = 25.8 trên tập phát triển newstest2013, khớp với đáp án."
|
| 143 |
+
}
|
| 144 |
+
},
|
| 145 |
+
"4": {
|
| 146 |
+
"supported_by_embeddings": true,
|
| 147 |
+
"max_similarity": 0.6373076438903809,
|
| 148 |
+
"evidence": [
|
| 149 |
+
{
|
| 150 |
+
"idx": 36,
|
| 151 |
+
"page": 7,
|
| 152 |
+
"score": 0.6373076438903809,
|
| 153 |
+
"text": "Each training\nbatch contained a set of sentence pairs containing approximately 25000 source tokens and 25000\ntarget tokens. **5.2** **Hardware and Schedule**\n\n\nWe trained our models on one machine with 8 NVIDIA P100 GPUs. For our base models using\nthe hyperparameters described throughout the paper, each training step took about 0.4 seconds. We\ntrained the base models for a total of 100,000 steps or 12 hours. For our big models,(described on the\nbottom line of table 3), step time was 1.0 seconds. The big models were trained for 300,000 steps\n(3.5 days). **5.3** **Optimizer**\n\n\nWe used the Adam optimizer [ 20 ] with _β_ 1 = 0 _._ 9, _β_ 2 = 0 _._ 98 and _ϵ_ = 10 _[−]_ [9] . We varied the learning\nrate over the course of training, according to the formula:\n\n\n_lrate_ = _d_ _[−]_ model [0] _[.]_ [5] _[·]_ [ min(] _[step]_ [_] _[num]_ _[−]_ [0] _[.]_ [5] _[, step]_ [_] _[num][ ·][ warmup]_ [_] _[steps]_ _[−]_ [1] _[.]_ [5] [)] (3)\n\n\nThis corresponds to increasing the learning rate linearly f..."
|
| 154 |
+
}
|
| 155 |
+
],
|
| 156 |
+
"model_verdict": {
|
| 157 |
+
"supported": true,
|
| 158 |
+
"confidence": 0.99,
|
| 159 |
+
"evidence": "We used _warmup_ _ _steps_ = 4000.",
|
| 160 |
+
"reason": "Context explicitly states that warmup steps were set to 4000, matching the answer."
|
| 161 |
+
}
|
| 162 |
+
},
|
| 163 |
+
"5": {
|
| 164 |
+
"supported_by_embeddings": true,
|
| 165 |
+
"max_similarity": 0.7000005841255188,
|
| 166 |
+
"evidence": [
|
| 167 |
+
{
|
| 168 |
+
"idx": 24,
|
| 169 |
+
"page": 8,
|
| 170 |
+
"score": 0.7000005841255188,
|
| 171 |
+
"text": "Table 2: The Transformer achieves better BLEU scores than previous state-of-the-art models on the\nEnglish-to-German and English-to-French newstest2014 tests at a fraction of the training cost. BLEU Training Cost (FLOPs)\nModel\n\nEN-DE EN-FR EN-DE EN-FR\nByteNet [18] 23.75\nDeep-Att + PosUnk [39] 39.2 1 _._ 0 _·_ 10 [20]\n\nGNMT + RL [38] 24.6 39.92 2 _._ 3 _·_ 10 [19] 1 _._ 4 _·_ 10 [20]\n\nConvS2S [9] 25.16 40.46 9 _._ 6 _·_ 10 [18] 1 _._ 5 _·_ 10 [20]\n\nMoE [32] 26.03 40.56 2 _._ 0 _·_ 10 [19] 1 _._ 2 _·_ 10 [20]\n\nDeep-Att + PosUnk Ensemble [39] 40.4 8 _._ 0 _·_ 10 [20]\n\nGNMT + RL Ensemble [38] 26.30 41.16 1 _._ 8 _·_ 10 [20] 1 _._ 1 _·_ 10 [21]\n\nConvS2S Ensemble [9] 26.36 **41.29** 7 _._ 7 _·_ 10 [19] 1 _._ 2 _·_ 10 [21]\n\nTransformer (base model) 27.3 38.1 **3** _**.**_ **3** _**·**_ **10** **[18]**\n\nTransformer (big) **28.4** **41.8** 2 _._ 3 _·_ 10 [19]\n\n\n**Residual Dropout** We apply dropout [ 33 ] to the output of each sub-layer, before it is added to the\nsub-layer input and normalized. ..."
|
| 172 |
+
},
|
| 173 |
+
{
|
| 174 |
+
"idx": 1,
|
| 175 |
+
"page": 9,
|
| 176 |
+
"score": 0.5974264144897461,
|
| 177 |
+
"text": "Table 3: Variations on the Transformer architecture. Unlisted values are identical to those of the base\nmodel. All metrics are on the English-to-German translation development set, newstest2013. Listed\nperplexities are per-wordpiece, according to our byte-pair encoding, and should not be compared to\nper-word perplexities. |Col1|train<br>N d d h d d P ϵ<br>model ff k v drop ls steps|PPL BLEU params<br>(dev) (dev) ×106|\n|---|---|---|\n|base|6<br>512<br>2048<br>8<br>64<br>64<br>0.1<br>0.1<br>100K|4.92<br>25.8<br>65|\n|(A)|1<br>512<br>512<br>4<br>128<br>128<br>16<br>32<br>32<br>32<br>16<br>16|5.29<br>24.9<br>5.00<br>25.5<br>4.91<br>25.8<br>5.01<br>25.4|\n|(B)|16<br>32|5.16<br>25.1<br>58<br>5.01<br>25.4<br>60|\n|(C)|2<br>4<br>8<br>256<br>32<br>32<br>1024<br>128<br>128<br>1024<br>4096|6.11<br>23.7<br>36<br>5.19<br>25.3<br>50<br>4.88<br>25.5<br>80<br>5.75<br>24.5<br>28<br>4.66<br>26.0<br>168<br>5.12<br>25.4<br>53<br>4.75<br>26.2<br>90|\n|(D)|0.0<br>0.2<br>0.0<br>0.2|5.77<br>24.6<br>4.95<br>25.5<br..."
|
| 178 |
+
},
|
| 179 |
+
{
|
| 180 |
+
"idx": 32,
|
| 181 |
+
"page": 1,
|
| 182 |
+
"score": 0.5703283548355103,
|
| 183 |
+
"text": "Experiments on two machine translation tasks show these models to\nbe superior in quality while being more parallelizable and requiring significantly\nless time to train. Our model achieves 28.4 BLEU on the WMT 2014 Englishto-German translation task, improving over the existing best results, including\nensembles, by over 2 BLEU. On the WMT 2014 English-to-French translation task,\nour model establishes a new single-model state-of-the-art BLEU score of 41.8 after\ntraining for 3.5 days on eight GPUs, a small fraction of the training costs of the\nbest models from the literature. We show that the Transformer generalizes well to\nother tasks by applying it successfully to English constituency parsing both with\nlarge and limited training data. _∗_ Equal contribution. Listing order is random. Jakob proposed replacing RNNs with self-attention and started\nthe effort to evaluate this idea. Ashish, with Illia, designed and implemented the first Transformer models and\nhas been crucially involved in eve..."
|
| 184 |
+
}
|
| 185 |
+
],
|
| 186 |
+
"model_verdict": {
|
| 187 |
+
"supported": true,
|
| 188 |
+
"confidence": 0.99,
|
| 189 |
+
"evidence": "Transformer (big) **28.4** ...; Our model achieves 28.4 BLEU on the WMT 2014 English-to-German translation task",
|
| 190 |
+
"reason": "Context explicitly states that the Transformer (big) model achieved a BLEU score of 28.4 on the English‑German WMT 2014 task."
|
| 191 |
+
}
|
| 192 |
+
}
|
| 193 |
+
}
|
| 194 |
+
}
|
test/ML_mcq_output.json
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"mcqs": {
|
| 3 |
+
"1": {
|
| 4 |
+
"câu hỏi": "Trong thuật toán K-Means, centroid của một cụm được định nghĩa như thế nào?",
|
| 5 |
+
"lựa chọn": {
|
| 6 |
+
"a": "Là điểm dữ liệu ngẫu nhiên được chọn làm trung tâm ban đầu của cụm.",
|
| 7 |
+
"b": "Là trung tâm hình học (geometric center) của tất cả các điểm trong cụm, tính bằng trung bình cộng các điểm thuộc cụm.",
|
| 8 |
+
"c": "Là điểm dữ liệu có khoảng cách lớn nhất tới các điểm còn lại trong cùng cụm.",
|
| 9 |
+
"d": "Là vị trí trung bình của các centroid của các cụm khác."
|
| 10 |
+
},
|
| 11 |
+
"đáp án": "Là trung tâm hình học (geometric center) của tất cả các điểm trong cụm, tính bằng trung bình cộng các điểm thuộc cụm."
|
| 12 |
+
},
|
| 13 |
+
"2": {
|
| 14 |
+
"câu hỏi": "Trong đoạn triển khai lớp KMeans bằng NumPy, câu lệnh nào sau đây khởi tạo các centroid một cách ngẫu nhiên?",
|
| 15 |
+
"lựa chọn": {
|
| 16 |
+
"a": "self.centroids = X[np.random.choice(X.shape[0], self.k, replace=False)]",
|
| 17 |
+
"b": "self.centroids = np.random.rand(self.k, X.shape[1])",
|
| 18 |
+
"c": "self.centroids = X[:self.k]",
|
| 19 |
+
"d": "self.centroids = np.zeros((self.k, X.shape[1]))"
|
| 20 |
+
},
|
| 21 |
+
"đáp án": "self.centroids = X[np.random.choice(X.shape[0], self.k, replace=False)]"
|
| 22 |
+
},
|
| 23 |
+
"3": {
|
| 24 |
+
"câu hỏi": "Trong mục \"Các thuộc tính của thuật toán K-means Clustering\" của tài liệu, đâu là mục không được liệt kê là một thuộc tính của thuật toán K-means?",
|
| 25 |
+
"lựa chọn": {
|
| 26 |
+
"a": "Thuộc tính thứ nhất của thuật toán K-means",
|
| 27 |
+
"b": "Thuộc tính thứ hai của thuật toán K-means",
|
| 28 |
+
"c": "Tại sao chúng ta cần phân cụm?",
|
| 29 |
+
"d": "Ứng dụng của phân cụm trong thực tế"
|
| 30 |
+
},
|
| 31 |
+
"đáp án": "Ứng dụng của phân cụm trong thực tế"
|
| 32 |
+
},
|
| 33 |
+
"4": {
|
| 34 |
+
"câu hỏi": "Trong thuật toán K-Means, bước nào được mô tả là “Mỗi điểm dữ liệu x_i được gán nhãn cụm l_i bằng cách chọn centroid gần nhất”?",
|
| 35 |
+
"lựa chọn": {
|
| 36 |
+
"a": "Bước khởi tạo (Initialization Step)",
|
| 37 |
+
"b": "Bước gán nhãn (Assignment Step)",
|
| 38 |
+
"c": "Bước cập nhật centroid (Update Step)",
|
| 39 |
+
"d": "Bước kiểm tra hội tụ (Convergence Check Step)"
|
| 40 |
+
},
|
| 41 |
+
"đáp án": "Bước gán nhãn (Assignment Step)"
|
| 42 |
+
},
|
| 43 |
+
"5": {
|
| 44 |
+
"câu hỏi": "Trong đoạn mã triển khai K-Means++, phương thức nào được sử dụng để khởi tạo centroids?",
|
| 45 |
+
"lựa chọn": {
|
| 46 |
+
"a": "kmeans_text.fit",
|
| 47 |
+
"b": "kmeans_plus_plus_init",
|
| 48 |
+
"c": "np.linalg.norm",
|
| 49 |
+
"d": "np.array"
|
| 50 |
+
},
|
| 51 |
+
"đáp án": "kmeans_plus_plus_init"
|
| 52 |
+
}
|
| 53 |
+
},
|
| 54 |
+
"validation": {
|
| 55 |
+
"1": {
|
| 56 |
+
"supported_by_embeddings": true,
|
| 57 |
+
"max_similarity": 0.6017358303070068,
|
| 58 |
+
"evidence": [
|
| 59 |
+
{
|
| 60 |
+
"idx": 18,
|
| 61 |
+
"page": 9,
|
| 62 |
+
"score": 0.6017358303070068,
|
| 63 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n\nvà nợcao, trong khi cụm xanh có thu nhập cao nhưng nợthấp. Rõ ràng cụm phân chia trong trường\nhợp II hợp lý hơn. Như vậy, các điểm dữliệu từcác cụm khác nhau nên khác biệt nhiều nhất có thểđểtạo thành các\ncụm có ý nghĩa hơn. Thuật toán K-means dùng phương pháp lặp đểtìm phân cụm tối ưu bằng cách\ngiảm thiểu tổng bình phương khoảng cách giữa các điểm và centroid của cụm. **5.3** **Tại sao chúng ta cần phân cụm?**\n\n\nChúng ta đã hiểu phân cụm là gì và các thuộc tính khác nhau của cụm. Vậy tại sao phải dùng phân\ncụm? Phần tiếp theo sẽgiải đáp thắc mắc này và giới thiệu một sốứng dụng thực tế. **6** **Ứng dụng của phân cụm trong thực tế**\n\n\nPhân cụm được sửdụng rộng rãi trong nhiều lĩnh vực, từngân hàng, hệthống đềxuất, đến phân cụm\nvăn bản và phân đoạn ảnh. - **Phân đoạn khách hàng:** Đây là ứng dụng phổbiến nhất của phân cụm, không chỉtrong ngân\nhàng mà còn trong viễn thông, thương mại điện tử, thểthao, quảng cáo, bán hàng,... - **Phân cụm văn bản:** N..."
|
| 64 |
+
},
|
| 65 |
+
{
|
| 66 |
+
"idx": 29,
|
| 67 |
+
"page": 5,
|
| 68 |
+
"score": 0.5860570669174194,
|
| 69 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n\n**4** **Thuật toán K-Means**\n\n\nThuật toán K-Means hoạt động như sau:\n\n\n1. **Đầu vào:** Tập dữliệu _X_ = _{x_ 1 _, x_ 2 _, . . ., x_ _n_ _}_ và sốlượng cụm _k_ .\n\n\n2. **Đầu ra:** Tập các centroid _{c_ 1 _, c_ 2 _, . . ., c_ _k_ _}_ và nhãn cụm tương ứng cho mỗi điểm dữliệu _{l_ 1 _, l_ 2 _, . . ., l_ _n_ _}_ .\n\n\n3. **Khởi tạo:** Chọn ng��u nhiên _k_ centroid ban đầu.\n\n\nHình 1: Chọn k centroid ban đầu\n\n\n4. **Khởi tạo biến** `converged` bằng `false` đểkiểm soát vòng lặp.\n\n\n5. **Lặp cho đến khi hội tụhoặc đạt sốlần lặp tối đa:**\n\n\n - **Bước gán nhãn (Assignment Step):** Mỗi điểm dữliệu _x_ _i_ được gán nhãn cụm _l_ _i_ bằng\ncách chọn centroid gần nhất:\n_l_ _i_ = arg min _∥x_ _i_ _−_ _c_ _j_ _∥_ [2]\n_j_\n\n\nHình 2: Bước gán nhãn\n\n\n4"
|
| 70 |
+
},
|
| 71 |
+
{
|
| 72 |
+
"idx": 3,
|
| 73 |
+
"page": 18,
|
| 74 |
+
"score": 0.5734704732894897,
|
| 75 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n\n**4** **Bước 4: Triển khai thuật toán K-Means chính**\n\n\nTiếp theo, chúng ta sẽđịnh nghĩa một sốđiều kiện đểtriển khai thuật toán K-Means Clustering."
|
| 76 |
+
}
|
| 77 |
+
],
|
| 78 |
+
"model_verdict": {
|
| 79 |
+
"supported": false,
|
| 80 |
+
"confidence": 0.9,
|
| 81 |
+
"evidence": "",
|
| 82 |
+
"reason": "Trong ngữ cảnh không có câu nào mô tả centroid là trung tâm hình học hay tính bằng trung bình cộng các điểm; chỉ đề cập tới việc giảm thiểu khoảng cách và khởi tạo centroid ngẫu nhiên."
|
| 83 |
+
}
|
| 84 |
+
},
|
| 85 |
+
"2": {
|
| 86 |
+
"supported_by_embeddings": true,
|
| 87 |
+
"max_similarity": 0.5771877765655518,
|
| 88 |
+
"evidence": [
|
| 89 |
+
{
|
| 90 |
+
"idx": 15,
|
| 91 |
+
"page": 17,
|
| 92 |
+
"score": 0.5771877765655518,
|
| 93 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n\n12 `plt.ylabel(’Loan` `Amount (Thousands) ’)`\n\n13 `plt.show ()`\n\n\nListing 3: Chọn biến và trực quan hóa dữliệu\n\n\n**3** **Bước 3: Chọn sốcụm và khởi tạo centroids**\n\n\nBước 1 và 2 của K-Means là vềviệc chọn sốlượng cụm (k) và chọn các centroids ngẫu nhiên cho mỗi\ncụm. Chúng ta sẽchọn 3 cụm và sau đó chọn các quan sát ngẫu nhiên từdữliệu làm centroids:\n\n\n1 `# Step 1 and 2 - Choose the number of clusters (k) and` `randomly` `select` `centroids` `for`\n\n```\n each cluster\n\n```\n\n2\n\n\n3 `# number of clusters`\n\n\n4 `K = 3`\n\n\n5\n\n\n6 `# Randomly` `select` `observations as centroids`\n\n7 `Centroids = X.sample(n=K)`\n\n8 `plt.scatter(X[\" ApplicantIncome \"], X[\" LoanAmount \"], c=’black ’)`\n\n9 `plt.scatter(Centroids [\" ApplicantIncome \"], Centroids [\" LoanAmount \"], c=’red ’)`\n\n10 `plt.xlabel(’Annual Income ’)`\n\n11 `plt.ylabel(’Loan` `Amount (Thousands) ’)`\n\n\nListing 4: Chọn sốcụm và khởi tạo centroids\n\n\nỞđây, các chấm đỏđại diện cho 3 centroids của mỗi cụm. Lưu ý rằ..."
|
| 94 |
+
},
|
| 95 |
+
{
|
| 96 |
+
"idx": 20,
|
| 97 |
+
"page": 18,
|
| 98 |
+
"score": 0.5511029958724976,
|
| 99 |
+
"text": "Hãy\n\nxem mã trước:\n\n\n1 `# Step 3 - Assign all points to the` `nearest` `cluster` `centroid`\n\n2 `# Step 4 - Recalculate` `the` `centroids of the newly` `formed` `clusters`\n\n3 `# Step 5 - Repeat` `steps 3 and 4`\n\n\n4\n\n\n5 `diff = 1`\n\n\n6 `j = 0`\n\n\n7\n\n\n8 `while` `diff != 0:`\n\n\n9 `XD = X.copy ()`\n\n\n10 `i = 1`\n\n\n11 `for index1, row_c in Centroids.iterrows ():`\n\n\n12 `ED = []`\n\n\n13 `for index2, row_d in XD.iterrows ():`\n\n14 `d1 = (row_c [\" ApplicantIncome \"] - row_d [\" ApplicantIncome \"]) **2`\n\n15 `d2 = (row_c [\" LoanAmount \"] - row_d [\" LoanAmount \"]) **2`\n\n16 `d = np.sqrt(d1 + d2)`\n\n17 `ED.append(d)`\n\n18 `X[i] = ED`\n\n\n19 `i += 1`\n\n\n20\n\n\n21 `C = []`\n\n\n22 `for index, row in X.iterrows ():`\n\n23 `min_dist = row [1]`\n\n\n24 `pos = 1`\n\n25 `for i in range(K):`\n\n26 `if row[i + 1] < min_dist:`\n\n\n27 `min_dist = row[i + 1]`\n\n\n28 `pos = i + 1`\n\n29 `C.append(pos)`\n\n30 `X[\" Cluster \"] = C`\n\n31 `Centroids_new = X.groupby ([\" Cluster \"]).mean ()[[\" LoanAmount\", \" ApplicantIncome \"]]`\n\n\n32\n\n\n33 `if j == 0:`\n\n\n34..."
|
| 100 |
+
},
|
| 101 |
+
{
|
| 102 |
+
"idx": 30,
|
| 103 |
+
"page": 15,
|
| 104 |
+
"score": 0.550550639629364,
|
| 105 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n\n21 `return np.array(centroids)`\n\n\n22\n\n\n23 `# Using K-Means ++`\n\n24 `class` `KMeansPlusPlus(KMeans):`\n\n\n25 `def fit(self, X):`\n\n\n26 `# Use K-Means ++ initialization`\n\n\n27 `self.centroids = kmeans_plus_plus_init (X, self.k)`\n\n\n28\n\n\n29 `# Continue as in regular K-Means`\n\n30 `for i in range` `(self.max_iters):`\n\n31 `distances = np.linalg.norm(X[:, np.newaxis, :] - self.centroids, axis =2)`\n\n32 `labels = np.argmin(distances, axis =1)`\n\n\n33\n\n\n34 `new_centroids = np.array ([X[labels == j]. mean(axis =0) for j in range` `(self.`\n```\n k)])\n\n```\n\n35\n\n\n36 `if np.` `all` `(np.` `abs` `(self.centroids - new_centroids ) < 1e-4):`\n\n\n37 `break`\n\n\n38\n\n\n39 `self.centroids = new_centroids`\n\n\n40\n\n\n41 `return` `labels`\n\n\n14"
|
| 106 |
+
}
|
| 107 |
+
],
|
| 108 |
+
"model_verdict": {
|
| 109 |
+
"supported": false,
|
| 110 |
+
"confidence": 0.9,
|
| 111 |
+
"evidence": "",
|
| 112 |
+
"reason": "Trong ngữ cảnh chỉ đề cập đến việc chọn centroids ngẫu nhiên bằng X.sample(n=K) hoặc các phương pháp khác, không có câu lệnh self.centroids = X[np.random.choice(...)] được nêu."
|
| 113 |
+
}
|
| 114 |
+
},
|
| 115 |
+
"3": {
|
| 116 |
+
"supported_by_embeddings": true,
|
| 117 |
+
"max_similarity": 0.7246736288070679,
|
| 118 |
+
"evidence": [
|
| 119 |
+
{
|
| 120 |
+
"idx": 3,
|
| 121 |
+
"page": 18,
|
| 122 |
+
"score": 0.7246736288070679,
|
| 123 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n\n**4** **Bước 4: Triển khai thuật toán K-Means chính**\n\n\nTiếp theo, chúng ta sẽđịnh nghĩa một sốđiều kiện đểtriển khai thuật toán K-Means Clustering."
|
| 124 |
+
},
|
| 125 |
+
{
|
| 126 |
+
"idx": 13,
|
| 127 |
+
"page": 4,
|
| 128 |
+
"score": 0.7182997465133667,
|
| 129 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n\nBài toán trên là ví dụđiển hình cho việc ứng dụng kỹthuật _clustering_ trong khai phá dữliệu, đặc\nbiệt là thuật toán **K-means clustering**, một trong những phương pháp phân nhóm phổbiến và đơn\ngiản nhất hiện nay. ## **2. Lý thuyết K-Means**\n\n\n**1** **Định nghĩa và Khái niệm cơ bản**\n\n\nK-Means là thuật toán học không giám sát (unsupervised learning) thuộc nhóm phân cụm (clustering),\nnhằm chia tập dữliệu gồm _n_ điểm dữliệu _{x_ 1 _, x_ 2 _, . . ., x_ _n_ _}_ với _x_ _i_ _∈_ R _[d]_ thành _k_ cụm _{C_ 1 _, C_ 2 _, . . ., C_ _k_ _}_\nsao cho:\n\n\n - **Cohesion (Tính gắn kết)** : Các điểm trong cùng một cụm có độtương tựcao nhất có thể\n\n\n - **Separation (Tính phân tách)** : Các điểm thuộc cụm khác nhau có độtương tựthấp nhất có\nthể\n\n\n - **Completeness (Tính đầy đủ)** : Mọi điểm dữliệu đều được gán vào đúng một cụm\n\n\n**2** **Khái niệm Centroid và Cluster**\n\n\n**Centroid** _µ_ _i_ của cụm _C_ _i_ là trung tâm hình học (geometric center) của tất cảcác điể..."
|
| 130 |
+
},
|
| 131 |
+
{
|
| 132 |
+
"idx": 0,
|
| 133 |
+
"page": 3,
|
| 134 |
+
"score": 0.6935104727745056,
|
| 135 |
+
"text": "Đây chính là lúc các thuật toán học máy không giám sát (unsupervised learning) như **K-means**\n**clustering** trởnên rất hữu ích. Thuật toán này cho phép tựđộng phân nhóm dữliệu dựa trên sựtương\nđồng giữa các điểm dữliệu mà không cần thông tin nhãn từtrước. Nhờvậy, K-means giúp phát hiện\ncấu trúc tiềm ẩn trong dữliệu và hỗtrợcác bước phân tích tiếp theo. **2** **Vấn đềcốt lõi**\n\n\nĐểminh họa cho bài toán phân nhóm không giám sát, hãy xem xét một ví dụđơn giản với dữliệu về\ntuổi và chi tiêu hàng tháng của 9 khách hàng như sau:\n\n|Index|Tuổi|Chi tiêu (USD)|\n|---|---|---|\n|1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9|18<br>20<br>22<br>30<br>34<br>40<br>60<br>66<br>70|80<br>90<br>85<br>50<br>64<br>60<br>30<br>40<br>25|\n\n\n\nBảng 1: Dữliệu mẫu vềkhách hàng\n\n\nMục tiêu của bài toán là phân chia tựđộng 9 khách hàng này thành 3 nhóm khác nhau, ví dụnhư\nnhóm _Trẻ_, _Trung niên_ và _Cao tuổi_, dựa trên đặc điểm tuổi tác và chi tiêu, mà không cần biết trước\nnhóm nhãn phân loại. Việc này sẽgiúp doanh nghi..."
|
| 136 |
+
}
|
| 137 |
+
],
|
| 138 |
+
"model_verdict": {
|
| 139 |
+
"supported": false,
|
| 140 |
+
"confidence": 0.9,
|
| 141 |
+
"evidence": "Context does not contain a list of attributes of K-means nor mention 'Ứng dụng của phân cụm trong thực tế' as an attribute.",
|
| 142 |
+
"reason": "Không có bằng chứng trong nội dung cung cấp rằng mục này được liệt kê hoặc không được liệt kê; do đó không thể khẳng định đáp án được chứng thực."
|
| 143 |
+
}
|
| 144 |
+
},
|
| 145 |
+
"4": {
|
| 146 |
+
"supported_by_embeddings": true,
|
| 147 |
+
"max_similarity": 0.6494988203048706,
|
| 148 |
+
"evidence": [
|
| 149 |
+
{
|
| 150 |
+
"idx": 0,
|
| 151 |
+
"page": 3,
|
| 152 |
+
"score": 0.6494988203048706,
|
| 153 |
+
"text": "Đây chính là lúc các thuật toán học máy không giám sát (unsupervised learning) như **K-means**\n**clustering** trởnên rất hữu ích. Thuật toán này cho phép tựđộng phân nhóm dữliệu dựa trên sựtương\nđồng giữa các điểm dữliệu mà không cần thông tin nhãn từtrước. Nhờvậy, K-means giúp phát hiện\ncấu trúc tiềm ẩn trong dữliệu và hỗtrợcác bước phân tích tiếp theo. **2** **Vấn đềcốt lõi**\n\n\nĐểminh họa cho bài toán phân nhóm không giám sát, hãy xem xét một ví dụđơn giản với dữliệu về\ntuổi và chi tiêu hàng tháng của 9 khách hàng như sau:\n\n|Index|Tuổi|Chi tiêu (USD)|\n|---|---|---|\n|1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9|18<br>20<br>22<br>30<br>34<br>40<br>60<br>66<br>70|80<br>90<br>85<br>50<br>64<br>60<br>30<br>40<br>25|\n\n\n\nBảng 1: Dữliệu mẫu vềkhách hàng\n\n\nMục tiêu của bài toán là phân chia tựđộng 9 khách hàng này thành 3 nhóm khác nhau, ví dụnhư\nnhóm _Trẻ_, _Trung niên_ và _Cao tuổi_, dựa trên đặc điểm tuổi tác và chi tiêu, mà không cần biết trước\nnhóm nhãn phân loại. Việc này sẽgiúp doanh nghi..."
|
| 154 |
+
},
|
| 155 |
+
{
|
| 156 |
+
"idx": 3,
|
| 157 |
+
"page": 18,
|
| 158 |
+
"score": 0.6462726593017578,
|
| 159 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n\n**4** **Bước 4: Triển khai thuật toán K-Means chính**\n\n\nTiếp theo, chúng ta sẽđịnh nghĩa một sốđiều kiện đểtriển khai thuật toán K-Means Clustering."
|
| 160 |
+
},
|
| 161 |
+
{
|
| 162 |
+
"idx": 18,
|
| 163 |
+
"page": 9,
|
| 164 |
+
"score": 0.6377543210983276,
|
| 165 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n\nvà nợcao, trong khi cụm xanh có thu nhập cao nhưng nợthấp. Rõ ràng cụm phân chia trong trường\nhợp II hợp lý hơn. Như vậy, các điểm dữliệu từcác cụm khác nhau nên khác biệt nhiều nhất có thểđểtạo thành các\ncụm có ý nghĩa hơn. Thuật toán K-means dùng phương pháp lặp đểtìm phân cụm tối ưu bằng cách\ngiảm thiểu tổng bình phương khoảng cách giữa các điểm và centroid của cụm. **5.3** **Tại sao chúng ta cần phân cụm?**\n\n\nChúng ta đã hiểu phân cụm là gì và các thuộc tính khác nhau của cụm. Vậy tại sao phải dùng phân\ncụm? Phần tiếp theo sẽgiải đáp thắc mắc này và giới thiệu một sốứng dụng thực tế. **6** **Ứng dụng của phân cụm trong thực tế**\n\n\nPhân cụm được sửdụng rộng rãi trong nhiều lĩnh vực, từngân hàng, hệthống đềxuất, đến phân cụm\nvăn bản và phân đoạn ảnh. - **Phân đoạn khách hàng:** Đây là ứng dụng phổbiến nhất của phân cụm, không chỉtrong ngân\nhàng mà còn trong viễn thông, thương mại điện tử, thểthao, quảng cáo, bán hàng,... - **Phân cụm văn bản:** N..."
|
| 166 |
+
}
|
| 167 |
+
],
|
| 168 |
+
"model_verdict": {
|
| 169 |
+
"supported": false,
|
| 170 |
+
"confidence": 0.9,
|
| 171 |
+
"evidence": "",
|
| 172 |
+
"reason": "Trong ngữ cảnh cung cấp không có đoạn nào mô tả bước gán nhãn như “Mỗi điểm dữ liệu x_i được gán nhãn cụm l_i bằng cách chọn centroid gần nhất”, vì vậy không có bằng chứng hỗ trợ đáp án."
|
| 173 |
+
}
|
| 174 |
+
},
|
| 175 |
+
"5": {
|
| 176 |
+
"supported_by_embeddings": true,
|
| 177 |
+
"max_similarity": 0.590252161026001,
|
| 178 |
+
"evidence": [
|
| 179 |
+
{
|
| 180 |
+
"idx": 30,
|
| 181 |
+
"page": 15,
|
| 182 |
+
"score": 0.590252161026001,
|
| 183 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n\n21 `return np.array(centroids)`\n\n\n22\n\n\n23 `# Using K-Means ++`\n\n24 `class` `KMeansPlusPlus(KMeans):`\n\n\n25 `def fit(self, X):`\n\n\n26 `# Use K-Means ++ initialization`\n\n\n27 `self.centroids = kmeans_plus_plus_init (X, self.k)`\n\n\n28\n\n\n29 `# Continue as in regular K-Means`\n\n30 `for i in range` `(self.max_iters):`\n\n31 `distances = np.linalg.norm(X[:, np.newaxis, :] - self.centroids, axis =2)`\n\n32 `labels = np.argmin(distances, axis =1)`\n\n\n33\n\n\n34 `new_centroids = np.array ([X[labels == j]. mean(axis =0) for j in range` `(self.`\n```\n k)])\n\n```\n\n35\n\n\n36 `if np.` `all` `(np.` `abs` `(self.centroids - new_centroids ) < 1e-4):`\n\n\n37 `break`\n\n\n38\n\n\n39 `self.centroids = new_centroids`\n\n\n40\n\n\n41 `return` `labels`\n\n\n14"
|
| 184 |
+
},
|
| 185 |
+
{
|
| 186 |
+
"idx": 29,
|
| 187 |
+
"page": 5,
|
| 188 |
+
"score": 0.5836479663848877,
|
| 189 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n\n**4** **Thuật toán K-Means**\n\n\nThuật toán K-Means hoạt động như sau:\n\n\n1. **Đầu vào:** Tập dữliệu _X_ = _{x_ 1 _, x_ 2 _, . . ., x_ _n_ _}_ và sốlượng cụm _k_ .\n\n\n2. **Đầu ra:** Tập các centroid _{c_ 1 _, c_ 2 _, . . ., c_ _k_ _}_ và nhãn cụm tương ứng cho mỗi điểm dữliệu _{l_ 1 _, l_ 2 _, . . ., l_ _n_ _}_ .\n\n\n3. **Khởi tạo:** Chọn ngẫu nhiên _k_ centroid ban đầu.\n\n\nHình 1: Chọn k centroid ban đầu\n\n\n4. **Khởi tạo biến** `converged` bằng `false` đểkiểm soát vòng lặp.\n\n\n5. **Lặp cho đến khi hội tụhoặc đạt sốlần lặp tối đa:**\n\n\n - **Bước gán nhãn (Assignment Step):** Mỗi điểm dữliệu _x_ _i_ được gán nhãn cụm _l_ _i_ bằng\ncách chọn centroid gần nhất:\n_l_ _i_ = arg min _∥x_ _i_ _−_ _c_ _j_ _∥_ [2]\n_j_\n\n\nHình 2: Bước gán nhãn\n\n\n4"
|
| 190 |
+
},
|
| 191 |
+
{
|
| 192 |
+
"idx": 32,
|
| 193 |
+
"page": 2,
|
| 194 |
+
"score": 0.5471374988555908,
|
| 195 |
+
"text": ". . . . . . . . . . . . . . . . . . . . . 13\n\n2 K-Means++ Initialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13\n\n\n**1** **Phần II: Triển khai Thuật toán K-Means từđầu trong Python** **15**\n1 Bước 1: Import các thư viện cần thiết . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15\n2 B��ớc 2: Đọc và khám phá dữliệu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15\n3 Bước 3: Chọn sốcụm và khởi tạo centroids . . . . . . . . . . . . . . . . . . . . . . . . . 16\n4 Bước 4: Triển khai thuật toán K-Means chính . . . . . . . . . . . . . . . . . . . . . . . . 17\n5 Bước 5: Trực quan hóa kết quả . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17\n\n\n1"
|
| 196 |
+
}
|
| 197 |
+
],
|
| 198 |
+
"model_verdict": {
|
| 199 |
+
"supported": true,
|
| 200 |
+
"confidence": 1.0,
|
| 201 |
+
"evidence": "self.centroids = kmeans_plus_plus_init (X, self.k)",
|
| 202 |
+
"reason": "Đoạn mã cho thấy centroids được khởi tạo bằng hàm kmeans_plus_plus_init"
|
| 203 |
+
}
|
| 204 |
+
}
|
| 205 |
+
}
|
| 206 |
+
}
|
test/calculus_mcq_output.json
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"mcqs": {
|
| 3 |
+
"1": {
|
| 4 |
+
"câu hỏi": "Theo nội dung, khi D là miền hình chữ nhật a ≤ x ≤ b, c ≤ y ≤ d, biểu thức nào sau đây đúng cho tích phân kép \\(\\iint_D f(x,y)\\,dxdy\\)?",
|
| 5 |
+
"lựa chọn": {
|
| 6 |
+
"a": "∫_a^b ∫_c^d f(x,y) dy dx",
|
| 7 |
+
"b": "∫_c^d ∫_a^b f(x,y) dx dy",
|
| 8 |
+
"c": "∫_a^b ∫_c^d f(x,y) dy dx = ∫_c^d ∫_a^b f(x,y) dx dy",
|
| 9 |
+
"d": "Không có biểu thức nào đúng"
|
| 10 |
+
},
|
| 11 |
+
"đáp án": "∫_a^b ∫_c^d f(x,y) dy dx = ∫_c^d ∫_a^b f(x,y) dx dy"
|
| 12 |
+
},
|
| 13 |
+
"2": {
|
| 14 |
+
"câu hỏi": "Theo Định nghĩa 1.3, một mặt phẳng có phương trình ax + by + cz + d = 0 có thể được biểu diễn tham số như thế nào?",
|
| 15 |
+
"lựa chọn": {
|
| 16 |
+
"a": "x = u, y = v, z = -(d + a u + b v)/c",
|
| 17 |
+
"b": "x = u, y = v, z = d + a u + b v",
|
| 18 |
+
"c": "x = u, y = v, z = (d - a u - b v)/c",
|
| 19 |
+
"d": "x = u, y = v, z = (a u + b v - d)/c"
|
| 20 |
+
},
|
| 21 |
+
"đáp án": "x = u, y = v, z = -(d + a u + b v)/c"
|
| 22 |
+
},
|
| 23 |
+
"3": {
|
| 24 |
+
"câu hỏi": "Phương trình tiếp tuyến (tangent plane) của mặt cong x² − 4y² + 2z² = 6 tại điểm (2, 2, 3) là:",
|
| 25 |
+
"lựa chọn": {
|
| 26 |
+
"a": "x − 4y + 3z = 3",
|
| 27 |
+
"b": "x + 4y − 3z = 3",
|
| 28 |
+
"c": "2x − 8y + 6z = 6",
|
| 29 |
+
"d": "x − 4y + 3z = 0"
|
| 30 |
+
},
|
| 31 |
+
"đáp án": "x − 4y + 3z = 3"
|
| 32 |
+
},
|
| 33 |
+
"4": {
|
| 34 |
+
"câu hỏi": "Trong tiêu đề của bài giảng \"GIẢI TÍCH II\" tại Trường Đại học Bách Khoa Hà Nội, các phép tính nào được liệt kê là ứng dụng?",
|
| 35 |
+
"lựa chọn": {
|
| 36 |
+
"a": "Các ứng dụng của phép tính vi phân, tích phân bộ, tích phân phụ thuộc tham số, tích phân đường, tích phân mặt, lý thuyết",
|
| 37 |
+
"b": "Bài giảng về giải tích I",
|
| 38 |
+
"c": "Giảng viên TS. Bùi Xuân Diệu",
|
| 39 |
+
"d": "Ngày cập nhật 28 tháng 8 năm 2017"
|
| 40 |
+
},
|
| 41 |
+
"đáp án": "Các ứng dụng của phép tính vi phân, tích phân bộ, tích phân phụ thuộc tham số, tích phân đường, tích phân mặt, lý thuyết"
|
| 42 |
+
},
|
| 43 |
+
"5": {
|
| 44 |
+
"câu hỏi": "Khi chia miền R thành m × n hình chữ nhật con có độ dài bằng nhau, ký hiệu của một hình chữ nhật con R_{ij} được cho bởi:",
|
| 45 |
+
"lựa chọn": {
|
| 46 |
+
"a": "R_{ij} = [x_i, x_{i+1}] × [y_j, y_{j+1}]",
|
| 47 |
+
"b": "R_{ij} = [x_{i-1}, x_i] × [y_{j-1}, y_j]",
|
| 48 |
+
"c": "R_{ij} = [x_{i}, x_{i-1}] × [y_{j}, y_{j-1}]",
|
| 49 |
+
"d": "R_{ij} = [x_{i-1}, x_{i+1}] × [y_{j-1}, y_{j+1}]"
|
| 50 |
+
},
|
| 51 |
+
"đáp án": "R_{ij} = [x_{i-1}, x_i] × [y_{j-1}, y_j]"
|
| 52 |
+
}
|
| 53 |
+
},
|
| 54 |
+
"validation": {
|
| 55 |
+
"1": {
|
| 56 |
+
"supported_by_embeddings": true,
|
| 57 |
+
"max_similarity": 0.8958114981651306,
|
| 58 |
+
"evidence": [
|
| 59 |
+
{
|
| 60 |
+
"idx": 74,
|
| 61 |
+
"page": 30,
|
| 62 |
+
"score": 0.8958114981651306,
|
| 63 |
+
"text": "_28_ _Chương 2. Tích phân bội_\n\n\n**Chú ý 2.3.** Nếu tồn tại tích phân kép f ( x, y ) dxdy thì ta nói hàm số f ( x, y ) khảtích\n��\n\nD\n\ntrong miền D .\n\n\n**Tính chất cơ bản:**\n\n\n Tính chất tuyến tính:\n\n\n\n��\n\n\n\nf ( x, y ) dxdy +\n��\nD D\n\n\n\n\n[ f ( x, y ) + g ( x, y )] dxdy =\n��\nD D\n\n\n\ng ( x, y ) dxdy\n\nD\n\n\n\n��\n\n\n\nk f ( x, y ) dxdy = k\n��\nD D\n\n\n\nf ( x, y ) dxdy\n\nD\n\n\n\n\n- Tính chất cộng tính: Nếu D = D 1 ∪ D 2, ởđó D 1 và D 2 không \"chồng\" lên nhau (có thể\nngoại trừphần biên) thì\n\n\n\n��\n\n\n\nf ( x, y ) dxdy =\n��\nD D\n\n\n\nf ( x, y ) dxdy.\n\n\n\nD 1\n\n\n\nf ( x, y ) dxdy +\n��\n\nD 2\n\n\n\n\n\n\n\n\n\n\n#### **1.2 Tính tích phân kép trong hệtoạđộDescartes**\n\nĐểtính các tích phân hai lớp, ta cần phải đưa vềtính các tích phân lặp.\n\n\n1. Nếu D là miền hình chữnhật ( D ) : a ⩽ x ⩽ b, c ⩽ y ⩽ d thì ta có thểsửdụng một\ntrong hai tích phân lặp\n\n\n\nd\n\n\ndy\n\n�\n\n\nc\n\n\n\nd\n\n\nf ( x, y ) dx.\n\n�\n\n\nc\n\n\n\nd\n\n\nf ( x, y ) dy =\n\n�\n\n\nc\n\n\n28\n\n\n\nf ( x, y ) dxdy =\n\n��\n\nD\n\n\n\nb\n\n\ndx\n\n�\n\n\na"
|
| 64 |
+
},
|
| 65 |
+
{
|
| 66 |
+
"idx": 50,
|
| 67 |
+
"page": 30,
|
| 68 |
+
"score": 0.8958114981651306,
|
| 69 |
+
"text": "_28_ _Chương 2. Tích phân bội_\n\n\n**Chú ý 2.3.** Nếu tồn tại tích phân kép f ( x, y ) dxdy thì ta nói hàm số f ( x, y ) khảtích\n��\n\nD\n\ntrong miền D .\n\n\n**Tính chất cơ bản:**\n\n\n Tính chất tuyến tính:\n\n\n\n��\n\n\n\nf ( x, y ) dxdy +\n��\nD D\n\n\n\n\n[ f ( x, y ) + g ( x, y )] dxdy =\n��\nD D\n\n\n\ng ( x, y ) dxdy\n\nD\n\n\n\n��\n\n\n\nk f ( x, y ) dxdy = k\n��\nD D\n\n\n\nf ( x, y ) dxdy\n\nD\n\n\n\n\n- Tính chất cộng tính: Nếu D = D 1 ∪ D 2, ởđó D 1 và D 2 không \"chồng\" lên nhau (có thể\nngoại trừphần biên) thì\n\n\n\n��\n\n\n\nf ( x, y ) dxdy =\n��\nD D\n\n\n\nf ( x, y ) dxdy.\n\n\n\nD 1\n\n\n\nf ( x, y ) dxdy +\n��\n\nD 2\n\n\n\n\n\n\n\n\n\n\n#### **1.2 Tính tích phân kép trong hệtoạđộDescartes**\n\nĐểtính các tích phân hai lớp, ta cần phải đưa vềtính các tích phân lặp.\n\n\n1. Nếu D là miền hình chữnhật ( D ) : a ⩽ x ⩽ b, c ⩽ y ⩽ d thì ta có thểsửdụng một\ntrong hai tích phân lặp\n\n\n\nd\n\n\ndy\n\n�\n\n\nc\n\n\n\nd\n\n\nf ( x, y ) dx.\n\n�\n\n\nc\n\n\n\nd\n\n\nf ( x, y ) dy =\n\n�\n\n\nc\n\n\n28\n\n\n\nf ( x, y ) dxdy =\n\n��\n\nD\n\n\n\nb\n\n\ndx\n\n�\n\n\na"
|
| 70 |
+
},
|
| 71 |
+
{
|
| 72 |
+
"idx": 38,
|
| 73 |
+
"page": 30,
|
| 74 |
+
"score": 0.8958114981651306,
|
| 75 |
+
"text": "_28_ _Chương 2. Tích phân bội_\n\n\n**Chú ý 2.3.** Nếu tồn tại tích phân kép f ( x, y ) dxdy thì ta nói hàm số f ( x, y ) khảtích\n��\n\nD\n\ntrong miền D .\n\n\n**Tính chất cơ bản:**\n\n\n Tính chất tuyến tính:\n\n\n\n��\n\n\n\nf ( x, y ) dxdy +\n��\nD D\n\n\n\n\n[ f ( x, y ) + g ( x, y )] dxdy =\n��\nD D\n\n\n\ng ( x, y ) dxdy\n\nD\n\n\n\n��\n\n\n\nk f ( x, y ) dxdy = k\n��\nD D\n\n\n\nf ( x, y ) dxdy\n\nD\n\n\n\n\n- Tính chất cộng tính: Nếu D = D 1 ∪ D 2, ởđó D 1 và D 2 không \"chồng\" lên nhau (có thể\nngoại trừphần biên) thì\n\n\n\n��\n\n\n\nf ( x, y ) dxdy =\n��\nD D\n\n\n\nf ( x, y ) dxdy.\n\n\n\nD 1\n\n\n\nf ( x, y ) dxdy +\n��\n\nD 2\n\n\n\n\n\n\n\n\n\n\n#### **1.2 Tính tích phân kép trong hệtoạđộDescartes**\n\nĐểtính các tích phân hai lớp, ta cần phải đưa vềtính các tích phân lặp.\n\n\n1. Nếu D là miền hình chữnhật ( D ) : a ⩽ x ⩽ b, c ⩽ y ⩽ d thì ta có thểsửdụng một\ntrong hai tích phân lặp\n\n\n\nd\n\n\ndy\n\n�\n\n\nc\n\n\n\nd\n\n\nf ( x, y ) dx.\n\n�\n\n\nc\n\n\n\nd\n\n\nf ( x, y ) dy =\n\n�\n\n\nc\n\n\n28\n\n\n\nf ( x, y ) dxdy =\n\n��\n\nD\n\n\n\nb\n\n\ndx\n\n�\n\n\na"
|
| 76 |
+
}
|
| 77 |
+
],
|
| 78 |
+
"model_verdict": {
|
| 79 |
+
"supported": true,
|
| 80 |
+
"confidence": 0.96,
|
| 81 |
+
"evidence": "Nếu D là miền hình chữ nhật ( D ) : a ≤ x ≤ b, c ≤ y ≤ d thì ta có thể sử dụng một trong hai tích phân lặp ... ∫_a^b ∫_c^d f(x,y) dy dx = ∫_c^d ∫_a^b f(x,y) dx dy",
|
| 82 |
+
"reason": "Đoạn văn nêu rõ rằng với miền hình chữ nhật, hai dạng tích phân lặp đều đúng và bằng nhau, nên đáp án c được chứng thực."
|
| 83 |
+
}
|
| 84 |
+
},
|
| 85 |
+
"2": {
|
| 86 |
+
"supported_by_embeddings": true,
|
| 87 |
+
"max_similarity": 0.7703134417533875,
|
| 88 |
+
"evidence": [
|
| 89 |
+
{
|
| 90 |
+
"idx": 46,
|
| 91 |
+
"page": 23,
|
| 92 |
+
"score": 0.7703134417533875,
|
| 93 |
+
"text": "Vậy:\n\n\n\n12 [−] [1] [=] [y] − [−] 4 [3]\n\n\n\n3\n\n\n\n**–** Phương trình tiếp tuyến ( d ) : [x] 12 [−] [1]\n\n\n\n− [−] 4 [=] [z] [−] 3 [4]\n\n\n\n**–** Phương trình pháp diện ( P ) : 12 ( x − 1 ) − 4 ( y − 3 ) + 3 ( z − 4 ) = 0\n\n\n\nb. Tương tự,\n\n\n\nn f = (− 8, 6, 12 )\n� n g = (− 4, 4, − 1 ) [,][ n] [ f] [ ∧] [n] [g] [ =][ −] [2] [ (] [27, 27, 4] [)] [ nên]\n\n\n\n\n[+] [2] [y] [−] [1]\n\n27 [=] 27\n\n\n\n4\n\n\n\n**–** Phương trình tiếp tuyến ( d ) : [x] 27 [+] [2]\n\n\n\n\n[−] [z] [−] [6]\n\n27 [=] 4\n\n\n\n**–** Phương trình pháp diện ( P ) : 27 ( x + 2 ) + 27 ( y − 1 ) + 4 ( z − 6 ) = 0\n\n\n21"
|
| 94 |
+
},
|
| 95 |
+
{
|
| 96 |
+
"idx": 31,
|
| 97 |
+
"page": 23,
|
| 98 |
+
"score": 0.7703134417533875,
|
| 99 |
+
"text": "Vậy:\n\n\n\n12 [−] [1] [=] [y] − [−] 4 [3]\n\n\n\n3\n\n\n\n**–** Phương trình tiếp tuyến ( d ) : [x] 12 [−] [1]\n\n\n\n− [−] 4 [=] [z] [−] 3 [4]\n\n\n\n**–** Phương trình pháp diện ( P ) : 12 ( x − 1 ) − 4 ( y − 3 ) + 3 ( z − 4 ) = 0\n\n\n\nb. Tương tự,\n\n\n\nn f = (− 8, 6, 12 )\n� n g = (− 4, 4, − 1 ) [,][ n] [ f] [ ∧] [n] [g] [ =][ −] [2] [ (] [27, 27, 4] [)] [ nên]\n\n\n\n\n[+] [2] [y] [−] [1]\n\n27 [=] 27\n\n\n\n4\n\n\n\n**–** Phương trình tiếp tuyến ( d ) : [x] 27 [+] [2]\n\n\n\n\n[−] [z] [−] [6]\n\n27 [=] 4\n\n\n\n**–** Phương trình pháp diện ( P ) : 27 ( x + 2 ) + 27 ( y − 1 ) + 4 ( z − 6 ) = 0\n\n\n21"
|
| 100 |
+
},
|
| 101 |
+
{
|
| 102 |
+
"idx": 23,
|
| 103 |
+
"page": 23,
|
| 104 |
+
"score": 0.7703134417533875,
|
| 105 |
+
"text": "Vậy:\n\n\n\n12 [−] [1] [=] [y] − [−] 4 [3]\n\n\n\n3\n\n\n\n**–** Phương trình tiếp tuyến ( d ) : [x] 12 [−] [1]\n\n\n\n− [−] 4 [=] [z] [−] 3 [4]\n\n\n\n**–** Phương trình pháp diện ( P ) : 12 ( x − 1 ) − 4 ( y − 3 ) + 3 ( z − 4 ) = 0\n\n\n\nb. Tương tự,\n\n\n\nn f = (− 8, 6, 12 )\n� n g = (− 4, 4, − 1 ) [,][ n] [ f] [ ∧] [n] [g] [ =][ −] [2] [ (] [27, 27, 4] [)] [ nên]\n\n\n\n\n[+] [2] [y] [−] [1]\n\n27 [=] 27\n\n\n\n4\n\n\n\n**–** Phương trình tiếp tuyến ( d ) : [x] 27 [+] [2]\n\n\n\n\n[−] [z] [−] [6]\n\n27 [=] 4\n\n\n\n**–** Phương trình pháp diện ( P ) : 27 ( x + 2 ) + 27 ( y − 1 ) + 4 ( z − 6 ) = 0\n\n\n21"
|
| 106 |
+
}
|
| 107 |
+
],
|
| 108 |
+
"model_verdict": {
|
| 109 |
+
"supported": false,
|
| 110 |
+
"confidence": 0.9,
|
| 111 |
+
"evidence": "",
|
| 112 |
+
"reason": "Context does not contain any statement about the parametric form of the plane ax + by + cz + d = 0, so the answer is not supported by the given text."
|
| 113 |
+
}
|
| 114 |
+
},
|
| 115 |
+
"3": {
|
| 116 |
+
"supported_by_embeddings": true,
|
| 117 |
+
"max_similarity": 0.7455167770385742,
|
| 118 |
+
"evidence": [
|
| 119 |
+
{
|
| 120 |
+
"idx": 160,
|
| 121 |
+
"page": 12,
|
| 122 |
+
"score": 0.7455167770385742,
|
| 123 |
+
"text": "_10_ _Chương 1. Các ứng dụng của phép tính vi phân trong hình học_\n\n\n3. Nếu họđường cong đã cho có điểm kì dịthì hệphương trình (1.2) bao gồm hình bao\n( E ) và quỹtích các điểm kì dịthuộc họcác đường cong đã cho. **Bài tập 1.1.** Viết phương trình tiếp tuyến và pháp tuyến với đường cong:\n\n\na) y = x [3] + 2x [2] − 4x − 3 tại (− 2, 5 ) . Phương trình pháp tuyến x = − 2\n\n\n\n_Lời giải_ . \n\n\n\n\nPhương trình tiếp tuyến y = 5\n\nPhương trình pháp tuyến x =\n\n\n\n\n\nb) y = e [1] [−] [x] [2] tại giao điểm của đường cong với đường thằng y = 1 . Phương trình pháp tuyến x + 2y − 1 = 0\n\n\n\n_Lời giải_ . **–** Tại M 1 (− 1, 1 ),\n\n\n\n\n\n\n\n\nPhương trình tiếp tuyến 2x − y + 3 = 0\n\nPhương trình pháp tuyến x + 2y − 1 =\n\n\n\nPhương trình pháp tuyến x − 2y + 1 = 0\n\n\n\n**–** Tại M 2 (− 1, 1 ),\n\n\n\n\n\n\n\n\nPhương trình tiếp tuyến 2x + y − 3 = 0\n\nPhương trình pháp tuyến x − 2y + 1 =\n\n\n\nc. x = [1] [+] [t]\n\nt [3]\n3\n\n� y = 2t [3]\n\n\n\nt [3]\n3\ny = 2t [3] [+] 2 [1]\n\n\n\ntại A ( 2, 2 ) . [1]\n\n2t\n\n\n\n_Lời giải_ . **–** Phương t..."
|
| 124 |
+
},
|
| 125 |
+
{
|
| 126 |
+
"idx": 108,
|
| 127 |
+
"page": 12,
|
| 128 |
+
"score": 0.7455167770385742,
|
| 129 |
+
"text": "_10_ _Chương 1. Các ứng dụng của phép tính vi phân trong hình học_\n\n\n3. Nếu họđường cong đã cho có điểm kì dịthì hệphương trình (1.2) bao gồm hình bao\n( E ) và quỹtích các điểm kì dịthuộc họcác đường cong đã cho. **Bài tập 1.1.** Viết phương trình tiếp tuyến và pháp tuyến với đường cong:\n\n\na) y = x [3] + 2x [2] − 4x − 3 tại (− 2, 5 ) . Phương trình pháp tuyến x = − 2\n\n\n\n_Lời giải_ . \n\n\n\n\nPhương trình tiếp tuyến y = 5\n\nPhương trình pháp tuyến x =\n\n\n\n\n\nb) y = e [1] [−] [x] [2] tại giao điểm của đường cong với đường thằng y = 1 . Phương trình pháp tuyến x + 2y − 1 = 0\n\n\n\n_Lời giải_ . **–** Tại M 1 (− 1, 1 ),\n\n\n\n\n\n\n\n\nPhương trình tiếp tuyến 2x − y + 3 = 0\n\nPhương trình pháp tuyến x + 2y − 1 =\n\n\n\nPhương trình pháp tuyến x − 2y + 1 = 0\n\n\n\n**–** Tại M 2 (− 1, 1 ),\n\n\n\n\n\n\n\n\nPhương trình tiếp tuyến 2x + y − 3 = 0\n\nPhương trình pháp tuyến x − 2y + 1 =\n\n\n\nc. x = [1] [+] [t]\n\nt [3]\n3\n\n� y = 2t [3]\n\n\n\nt [3]\n3\ny = 2t [3] [+] 2 [1]\n\n\n\ntại A ( 2, 2 ) . [1]\n\n2t\n\n\n\n_Lời giải_ . **–** Phương t..."
|
| 130 |
+
},
|
| 131 |
+
{
|
| 132 |
+
"idx": 106,
|
| 133 |
+
"page": 12,
|
| 134 |
+
"score": 0.7455167770385742,
|
| 135 |
+
"text": "_10_ _Chương 1. Các ứng dụng của phép tính vi phân trong hình học_\n\n\n3. Nếu họđường cong đã cho có điểm kì dịthì hệphương trình (1.2) bao gồm hình bao\n( E ) và quỹtích các điểm kì dịthuộc họcác đường cong đã cho. **Bài tập 1.1.** Viết phương trình tiếp tuyến và pháp tuyến với đường cong:\n\n\na) y = x [3] + 2x [2] − 4x − 3 tại (− 2, 5 ) . Phương trình pháp tuyến x = − 2\n\n\n\n_Lời giải_ . \n\n\n\n\nPhương trình tiếp tuyến y = 5\n\nPhương trình pháp tuyến x =\n\n\n\n\n\nb) y = e [1] [−] [x] [2] tại giao điểm của đường cong với đường thằng y = 1 . Phương trình pháp tuyến x + 2y − 1 = 0\n\n\n\n_Lời giải_ . **–** Tại M 1 (− 1, 1 ),\n\n\n\n\n\n\n\n\nPhương trình tiếp tuyến 2x − y + 3 = 0\n\nPhương trình pháp tuyến x + 2y − 1 =\n\n\n\nPhương trình pháp tuyến x − 2y + 1 = 0\n\n\n\n**–** Tại M 2 (− 1, 1 ),\n\n\n\n\n\n\n\n\nPhương trình tiếp tuyến 2x + y − 3 = 0\n\nPhương trình pháp tuyến x − 2y + 1 =\n\n\n\nc. x = [1] [+] [t]\n\nt [3]\n3\n\n� y = 2t [3]\n\n\n\nt [3]\n3\ny = 2t [3] [+] 2 [1]\n\n\n\ntại A ( 2, 2 ) . [1]\n\n2t\n\n\n\n_Lời giải_ . **–** Phương t..."
|
| 136 |
+
}
|
| 137 |
+
],
|
| 138 |
+
"model_verdict": {
|
| 139 |
+
"supported": false,
|
| 140 |
+
"confidence": 0.9,
|
| 141 |
+
"evidence": "",
|
| 142 |
+
"reason": "Trong nội dung cung cấp không có bất kỳ đề cập nào đến mặt cong x² − 4y² + 2z² = 6, điểm (2, 2, 3) hay phương trình tiếp tuyến của nó, vì vậy không thể chứng thực đáp án được."
|
| 143 |
+
}
|
| 144 |
+
},
|
| 145 |
+
"4": {
|
| 146 |
+
"supported_by_embeddings": true,
|
| 147 |
+
"max_similarity": 0.552233099937439,
|
| 148 |
+
"evidence": [
|
| 149 |
+
{
|
| 150 |
+
"idx": 160,
|
| 151 |
+
"page": 12,
|
| 152 |
+
"score": 0.552233099937439,
|
| 153 |
+
"text": "_10_ _Chương 1. Các ứng dụng của phép tính vi phân trong hình học_\n\n\n3. Nếu họđường cong đã cho có điểm kì dịthì hệphương trình (1.2) bao gồm hình bao\n( E ) và quỹtích các điểm kì dịthuộc họcác đường cong đã cho. **Bài tập 1.1.** Viết phương trình tiếp tuyến và pháp tuyến với đường cong:\n\n\na) y = x [3] + 2x [2] − 4x − 3 tại (− 2, 5 ) . Phương trình pháp tuyến x = − 2\n\n\n\n_Lời giải_ . \n\n\n\n\nPhương trình tiếp tuyến y = 5\n\nPhương trình pháp tuyến x =\n\n\n\n\n\nb) y = e [1] [−] [x] [2] tại giao điểm của đường cong với đường thằng y = 1 . Phương trình pháp tuyến x + 2y − 1 = 0\n\n\n\n_Lời giải_ . **–** Tại M 1 (− 1, 1 ),\n\n\n\n\n\n\n\n\nPhương trình tiếp tuyến 2x − y + 3 = 0\n\nPhương trình pháp tuyến x + 2y − 1 =\n\n\n\nPhương trình pháp tuyến x − 2y + 1 = 0\n\n\n\n**–** Tại M 2 (− 1, 1 ),\n\n\n\n\n\n\n\n\nPhương trình tiếp tuyến 2x + y − 3 = 0\n\nPhương trình pháp tuyến x − 2y + 1 =\n\n\n\nc. x = [1] [+] [t]\n\nt [3]\n3\n\n� y = 2t [3]\n\n\n\nt [3]\n3\ny = 2t [3] [+] 2 [1]\n\n\n\ntại A ( 2, 2 ) . [1]\n\n2t\n\n\n\n_Lời giải_ . **–** Phương t..."
|
| 154 |
+
},
|
| 155 |
+
{
|
| 156 |
+
"idx": 108,
|
| 157 |
+
"page": 12,
|
| 158 |
+
"score": 0.552233099937439,
|
| 159 |
+
"text": "_10_ _Chương 1. Các ứng dụng của phép tính vi phân trong hình học_\n\n\n3. Nếu họđường cong đã cho có điểm kì dịthì hệphương trình (1.2) bao gồm hình bao\n( E ) và quỹtích các điểm kì dịthuộc họcác đường cong đã cho. **Bài tập 1.1.** Viết phương trình tiếp tuyến và pháp tuyến với đường cong:\n\n\na) y = x [3] + 2x [2] − 4x − 3 tại (− 2, 5 ) . Phương trình pháp tuyến x = − 2\n\n\n\n_Lời giải_ . \n\n\n\n\nPhương trình tiếp tuyến y = 5\n\nPhương trình pháp tuyến x =\n\n\n\n\n\nb) y = e [1] [−] [x] [2] tại giao điểm của đường cong với đường thằng y = 1 . Phương trình pháp tuyến x + 2y − 1 = 0\n\n\n\n_Lời giải_ . **–** Tại M 1 (− 1, 1 ),\n\n\n\n\n\n\n\n\nPhương trình tiếp tuyến 2x − y + 3 = 0\n\nPhương trình pháp tuyến x + 2y − 1 =\n\n\n\nPhương trình pháp tuyến x − 2y + 1 = 0\n\n\n\n**–** Tại M 2 (− 1, 1 ),\n\n\n\n\n\n\n\n\nPhương trình tiếp tuyến 2x + y − 3 = 0\n\nPhương trình pháp tuyến x − 2y + 1 =\n\n\n\nc. x = [1] [+] [t]\n\nt [3]\n3\n\n� y = 2t [3]\n\n\n\nt [3]\n3\ny = 2t [3] [+] 2 [1]\n\n\n\ntại A ( 2, 2 ) . [1]\n\n2t\n\n\n\n_Lời giải_ . **–** Phương t..."
|
| 160 |
+
},
|
| 161 |
+
{
|
| 162 |
+
"idx": 106,
|
| 163 |
+
"page": 12,
|
| 164 |
+
"score": 0.552233099937439,
|
| 165 |
+
"text": "_10_ _Chương 1. Các ứng dụng của phép tính vi phân trong hình học_\n\n\n3. Nếu họđường cong đã cho có điểm kì dịthì hệphương trình (1.2) bao gồm hình bao\n( E ) và quỹtích các điểm kì dịthuộc họcác đường cong đã cho. **Bài tập 1.1.** Viết phương trình tiếp tuyến và pháp tuyến với đường cong:\n\n\na) y = x [3] + 2x [2] − 4x − 3 tại (− 2, 5 ) . Phương trình pháp tuyến x = − 2\n\n\n\n_Lời giải_ . \n\n\n\n\nPhương trình tiếp tuyến y = 5\n\nPhương trình pháp tuyến x =\n\n\n\n\n\nb) y = e [1] [−] [x] [2] tại giao điểm của đường cong với đường thằng y = 1 . Phương trình pháp tuyến x + 2y − 1 = 0\n\n\n\n_Lời giải_ . **–** Tại M 1 (− 1, 1 ),\n\n\n\n\n\n\n\n\nPhương trình tiếp tuyến 2x − y + 3 = 0\n\nPhương trình pháp tuyến x + 2y − 1 =\n\n\n\nPhương trình pháp tuyến x − 2y + 1 = 0\n\n\n\n**–** Tại M 2 (− 1, 1 ),\n\n\n\n\n\n\n\n\nPhương trình tiếp tuyến 2x + y − 3 = 0\n\nPhương trình pháp tuyến x − 2y + 1 =\n\n\n\nc. x = [1] [+] [t]\n\nt [3]\n3\n\n� y = 2t [3]\n\n\n\nt [3]\n3\ny = 2t [3] [+] 2 [1]\n\n\n\ntại A ( 2, 2 ) . [1]\n\n2t\n\n\n\n_Lời giải_ . **–** Phương t..."
|
| 166 |
+
}
|
| 167 |
+
],
|
| 168 |
+
"model_verdict": {
|
| 169 |
+
"supported": false,
|
| 170 |
+
"confidence": 0.9,
|
| 171 |
+
"evidence": "Ngữ cảnh không chứa tiêu đề 'GIẢI TÍCH II' hay danh sách các phép tính được liệt kê là ứng dụng.",
|
| 172 |
+
"reason": "Không có bằng chứng trong nội dung cung cấp để xác nhận đáp án."
|
| 173 |
+
}
|
| 174 |
+
},
|
| 175 |
+
"5": {
|
| 176 |
+
"supported_by_embeddings": true,
|
| 177 |
+
"max_similarity": 0.789191484451294,
|
| 178 |
+
"evidence": [
|
| 179 |
+
{
|
| 180 |
+
"idx": 156,
|
| 181 |
+
"page": 26,
|
| 182 |
+
"score": 0.789191484451294,
|
| 183 |
+
"text": "Như vậy ta đã chia miền][ R][ thành][ m] [ ×] [ n][ hình chữ]\n\n\n\ncon với độdài bằng nhau và bằng [d] [−] n [c] [. Như vậy ta đã chia miền][ R][ thành][ m] [ ×] [ n][ hình chữ]\n\nnhật con\nR ij = [ x i − 1, x i ] × [ y j − 1, y j ]\n\n\n\n24"
|
| 184 |
+
},
|
| 185 |
+
{
|
| 186 |
+
"idx": 79,
|
| 187 |
+
"page": 26,
|
| 188 |
+
"score": 0.789191484451294,
|
| 189 |
+
"text": "Như vậy ta đã chia miền][ R][ thành][ m] [ ×] [ n][ hình chữ]\n\n\n\ncon với độdài bằng nhau và bằng [d] [−] n [c] [. Như vậy ta đã chia miền][ R][ thành][ m] [ ×] [ n][ hình chữ]\n\nnhật con\nR ij = [ x i − 1, x i ] × [ y j − 1, y j ]\n\n\n\n24"
|
| 190 |
+
},
|
| 191 |
+
{
|
| 192 |
+
"idx": 13,
|
| 193 |
+
"page": 26,
|
| 194 |
+
"score": 0.789191484451294,
|
| 195 |
+
"text": "Như vậy ta đã chia miền][ R][ thành][ m] [ ×] [ n][ hình chữ]\n\n\n\ncon với độdài bằng nhau và bằng [d] [−] n [c] [. Như vậy ta đã chia miền][ R][ thành][ m] [ ×] [ n][ hình chữ]\n\nnhật con\nR ij = [ x i − 1, x i ] × [ y j − 1, y j ]\n\n\n\n24"
|
| 196 |
+
}
|
| 197 |
+
],
|
| 198 |
+
"model_verdict": {
|
| 199 |
+
"supported": true,
|
| 200 |
+
"confidence": 0.99,
|
| 201 |
+
"evidence": "R ij = [ x i − 1, x i ] × [ y j − 1, y j ]",
|
| 202 |
+
"reason": "Context explicitly gives the definition matching the answer"
|
| 203 |
+
}
|
| 204 |
+
}
|
| 205 |
+
}
|
| 206 |
+
}
|
test/cerebras-api.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
| 1 |
# import os
|
| 2 |
# from cerebras.cloud.sdk import Cerebras
|
| 3 |
-
import tiktoken
|
| 4 |
|
| 5 |
# client = Cerebras(
|
| 6 |
# # This is the default and can be omitted
|
|
@@ -20,29 +19,14 @@ import tiktoken
|
|
| 20 |
# temperature=1,
|
| 21 |
# top_p=1
|
| 22 |
# )
|
| 23 |
-
import numpy as np
|
| 24 |
|
| 25 |
-
|
| 26 |
-
OUTPUT_TOKEN_COUNT = np.array([], dtype=int)
|
| 27 |
|
| 28 |
-
#
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
text = f.read()
|
| 32 |
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
enc = tiktoken.encoding_for_model(model_name)
|
| 38 |
-
except Exception:
|
| 39 |
-
enc = None
|
| 40 |
-
|
| 41 |
-
if enc is None:
|
| 42 |
-
enc = tiktoken.get_encoding(encoding_name)
|
| 43 |
-
|
| 44 |
-
return len(enc.encode(text))
|
| 45 |
-
|
| 46 |
-
c = count_tokens(text)
|
| 47 |
-
INPUT_TOKEN_COUNT = np.append(INPUT_TOKEN_COUNT, c)
|
| 48 |
-
print(INPUT_TOKEN_COUNT)
|
|
|
|
| 1 |
# import os
|
| 2 |
# from cerebras.cloud.sdk import Cerebras
|
|
|
|
| 3 |
|
| 4 |
# client = Cerebras(
|
| 5 |
# # This is the default and can be omitted
|
|
|
|
| 19 |
# temperature=1,
|
| 20 |
# top_p=1
|
| 21 |
# )
|
|
|
|
| 22 |
|
| 23 |
+
my_dict = {'apple': 1, 'banana': 2, 'cherry': 3}
|
|
|
|
| 24 |
|
| 25 |
+
# Enumerate through both keys and values
|
| 26 |
+
for index, (key, value) in enumerate(my_dict.items()):
|
| 27 |
+
print(f"Index: {index}, Key: {key}, Value: {value}")
|
|
|
|
| 28 |
|
| 29 |
+
# Enumerate only through keys (less common with dictionaries)
|
| 30 |
+
print("\nEnumerate through keys only:")
|
| 31 |
+
for index, key in enumerate(my_dict): # By default, iterating a dict iterates its keys
|
| 32 |
+
print(f"Index: {index}, Key: {key}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
test/context.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[page 9] #### **Cài đặt sắp xếp trộn**
|
| 2 |
+
|
| 3 |
+
[page 5] #### **Cài đặt sắp xếp vun đống**
|
| 4 |
+
|
| 5 |
+
[page 2] ## **Các thuật toán sắp xếp - phần 2**
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
Sắp xếp vun đống (heap sort)
|
| 9 |
+
|
| 10 |
+
Sắp xếp trộn (merge sort)
|
| 11 |
+
|
| 12 |
+
Sắp xếp nhanh (quick sort)
|
test/general_mcq_output.json
ADDED
|
@@ -0,0 +1,664 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"mcqs": {
|
| 3 |
+
"1": {
|
| 4 |
+
"câu hỏi": "Theo chứng minh tính chất 2 (Bịchặn) dựa trên bất đẳng thức Cauchy‑Schwarz, khi nào giá trị K cos(x_j , q) bằng -1?",
|
| 5 |
+
"lựa chọn": {
|
| 6 |
+
"a": "K cos(x_j , q) = -1 nếu x_j và q vuông góc",
|
| 7 |
+
"b": "K cos(x_j , q) = -1 nếu x_j và q cùng hướng",
|
| 8 |
+
"c": "K cos(x_j , q) = -1 nếu x_j và q ngược hướng: x_j = c·q với c < 0",
|
| 9 |
+
"d": "K cos(x_j , q) = -1 nếu x_j = 0 hoặc q = 0"
|
| 10 |
+
},
|
| 11 |
+
"đáp án": "K cos(x_j , q) = -1 nếu x_j và q ngược hướng: x_j = c·q với c < 0"
|
| 12 |
+
},
|
| 13 |
+
"2": {
|
| 14 |
+
"câu hỏi": "Các bước chính trong quy trình xử lý của BERT cho bài toán phân loại tin nhắn spam/ham bao gồm những gì?",
|
| 15 |
+
"lựa chọn": {
|
| 16 |
+
"a": "Mã hóa đầu vào, Tạo embedding từ [MASK] và Đánh giá độ chính xác",
|
| 17 |
+
"b": "Mã hóa đầu vào, Xử lý qua Transformer encoder và Phân loại",
|
| 18 |
+
"c": "Tiền xử lý dữ liệu, Huấn luyện mô hình CNN và Dự đoán nhãn",
|
| 19 |
+
"d": "Phân tách token, Áp dụng TF-IDF và Sử dụng Naive Bayes"
|
| 20 |
+
},
|
| 21 |
+
"đáp án": "Mã hóa đầu vào, Xử lý qua Transformer encoder và Phân loại"
|
| 22 |
+
},
|
| 23 |
+
"3": {
|
| 24 |
+
"câu hỏi": "Trong hệ thống phân loại spam, loại spam nào được mô tả là nguy hiểm nhất, nhằm lừa đảo người dùng cung cấp thông tin cá nhân?",
|
| 25 |
+
"lựa chọn": {
|
| 26 |
+
"a": "Spam khác (Miscellaneous Spam)",
|
| 27 |
+
"b": "Spam hệ thống/lừa đảo (Phishing/System Spam)",
|
| 28 |
+
"c": "Spam quảng cáo",
|
| 29 |
+
"d": "Spam tinh vi (Sophisticated Spam)"
|
| 30 |
+
},
|
| 31 |
+
"đáp án": "Spam hệ thống/lừa đảo (Phishing/System Spam)"
|
| 32 |
+
},
|
| 33 |
+
"4": {
|
| 34 |
+
"câu hỏi": "Trong quy trình phân loại spam/ham được mô tả, vector nào được đưa vào lớp tuyến tính để dự đoán nhãn?",
|
| 35 |
+
"lựa chọn": {
|
| 36 |
+
"a": "Các embedding của từng token trong câu",
|
| 37 |
+
"b": "[CLS] vector",
|
| 38 |
+
"c": "Các trọng số attention",
|
| 39 |
+
"d": "Đầu ra của mạng FFN"
|
| 40 |
+
},
|
| 41 |
+
"đáp án": "[CLS] vector"
|
| 42 |
+
},
|
| 43 |
+
"5": {
|
| 44 |
+
"câu hỏi": "Theo nội dung đã cho, yếu tố nào sau đây được nêu là nhược điểm khi sử dụng mô hình học sâu để tăng cường dataset?",
|
| 45 |
+
"lựa chọn": {
|
| 46 |
+
"a": "Yêu cầu tài nguyên tính toán lớn, thời gian và chi phí cao",
|
| 47 |
+
"b": "Có khả năng hiểu được sự khác biệt tinh tế giữa các cách diễn đạt",
|
| 48 |
+
"c": "Tạo ra các mẫu mới để mở rộng dữ liệu",
|
| 49 |
+
"d": "Kết hợp BERT embeddings với nối từ khóa trong phương pháp bán giám sát"
|
| 50 |
+
},
|
| 51 |
+
"đáp án": "Yêu cầu tài nguyên tính toán lớn, thời gian và chi phí cao"
|
| 52 |
+
},
|
| 53 |
+
"6": {
|
| 54 |
+
"câu hỏi": "Theo nội dung, nhược điểm nào của mô hình được nêu ra?",
|
| 55 |
+
"lựa chọn": {
|
| 56 |
+
"a": "Đòi hỏi tài nguyên tính toán lớn",
|
| 57 |
+
"b": "Tăng cường dữ liệu",
|
| 58 |
+
"c": "Phương pháp semi-supervised",
|
| 59 |
+
"d": "Cải thiện hiệu suất ở k=5"
|
| 60 |
+
},
|
| 61 |
+
"đáp án": "Đòi hỏi tài nguyên tính toán lớn"
|
| 62 |
+
},
|
| 63 |
+
"7": {
|
| 64 |
+
"câu hỏi": "Trong hệ thống phân loại tin nhắn, tham số α có vai trò gì?",
|
| 65 |
+
"lựa chọn": {
|
| 66 |
+
"a": "Điều chỉnh mức độ ưu tiên của điểm saliency so với độ tương đồng tổng thể của tin nhắn.",
|
| 67 |
+
"b": "Xác định ngưỡng cho điểm bỏ phiếu.",
|
| 68 |
+
"c": "Chỉ định loại spam cụ thể.",
|
| 69 |
+
"d": "Đánh giá độ chính xác của mô hình."
|
| 70 |
+
},
|
| 71 |
+
"đáp án": "Điều chỉnh mức độ ưu tiên của điểm saliency so với độ tương đồng tổng thể của tin nhắn."
|
| 72 |
+
},
|
| 73 |
+
"8": {
|
| 74 |
+
"câu hỏi": "Trong hệ thống phân loại spam sử dụng FAISS, chỉ số nào được mô tả là sử dụng phép nhân vô hướng (Inner Product) để cho kết quả tương đương với độ tương đồng cosine?",
|
| 75 |
+
"lựa chọn": {
|
| 76 |
+
"a": "IndexFlatIP",
|
| 77 |
+
"b": "IndexIVFFlat",
|
| 78 |
+
"c": "IndexHNSW",
|
| 79 |
+
"d": "IndexPQ"
|
| 80 |
+
},
|
| 81 |
+
"đáp án": "IndexFlatIP"
|
| 82 |
+
},
|
| 83 |
+
"9": {
|
| 84 |
+
"câu hỏi": "Trong các loại spam được mô tả, loại nào được mô tả là nguy hiểm nhất, nhằm lừa đảo người dùng cung cấp thông tin cá nhân như mật khẩu, mã OTP hoặc thông tin thẻ tín dụng?",
|
| 85 |
+
"lựa chọn": {
|
| 86 |
+
"a": "Spam quảng cáo (Promotional Spam)",
|
| 87 |
+
"b": "Spam hệ thống/lừa đảo (Phishing/System Spam)",
|
| 88 |
+
"c": "Spam khác (Miscellaneous Spam)",
|
| 89 |
+
"d": "Spam không xác định"
|
| 90 |
+
},
|
| 91 |
+
"đáp án": "Spam hệ thống/lừa đảo (Phishing/System Spam)"
|
| 92 |
+
},
|
| 93 |
+
"10": {
|
| 94 |
+
"câu hỏi": "Phương pháp semi-supervised sub-category của spam được mô tả trong nội dung sử dụng kỹ thuật nào để tạo biểu diễn văn bản?",
|
| 95 |
+
"lựa chọn": {
|
| 96 |
+
"a": "Word2Vec",
|
| 97 |
+
"b": "BERT embeddings",
|
| 98 |
+
"c": "TF‑IDF",
|
| 99 |
+
"d": "LSTM"
|
| 100 |
+
},
|
| 101 |
+
"đáp án": "BERT embeddings"
|
| 102 |
+
},
|
| 103 |
+
"11": {
|
| 104 |
+
"câu hỏi": "Theo công thức kết hợp lồi được nêu trong nội dung, trọng số được tính như thế nào khi sử dụng tham số α?",
|
| 105 |
+
"lựa chọn": {
|
| 106 |
+
"a": "(1-α) × w_similarity + α × w_saliency",
|
| 107 |
+
"b": "(1-α) × w_similarity×ICF + α × w_saliency",
|
| 108 |
+
"c": "w_similarity×ICF + w_saliency",
|
| 109 |
+
"d": "α × w_similarity×ICF + (1-α) × w_saliency"
|
| 110 |
+
},
|
| 111 |
+
"đáp án": "(1-α) × w_similarity×ICF + α × w_saliency"
|
| 112 |
+
},
|
| 113 |
+
"12": {
|
| 114 |
+
"câu hỏi": "Theo bảng so sánh, độ chính xác của mô hình cải tiến với k = 1 tăng bao nhiêu phần trăm so với mô hình gốc?",
|
| 115 |
+
"lựa chọn": {
|
| 116 |
+
"a": "4.72%",
|
| 117 |
+
"b": "0.77%",
|
| 118 |
+
"c": "92%",
|
| 119 |
+
"d": "86.96%"
|
| 120 |
+
},
|
| 121 |
+
"đáp án": "4.72%"
|
| 122 |
+
},
|
| 123 |
+
"13": {
|
| 124 |
+
"câu hỏi": "Trong công thức trọng số mới đề xuất cho quá trình voting của KNN, yếu tố nào biểu thị tầm quan trọng tinh tế của từng thực thể?",
|
| 125 |
+
"lựa chọn": {
|
| 126 |
+
"a": "similarity( x_j , q )",
|
| 127 |
+
"b": "ICF( y( x_j ) )",
|
| 128 |
+
"c": "saliency( x_j , q )",
|
| 129 |
+
"d": "α (tham số cân bằng)"
|
| 130 |
+
},
|
| 131 |
+
"đáp án": "saliency( x_j , q )"
|
| 132 |
+
},
|
| 133 |
+
"14": {
|
| 134 |
+
"câu hỏi": "Trong kiến trúc BERT-base, mỗi lớp encoder có bao nhiêu head trong Multi-Head Self-Attention?",
|
| 135 |
+
"lựa chọn": {
|
| 136 |
+
"a": "8 head",
|
| 137 |
+
"b": "12 head",
|
| 138 |
+
"c": "16 head",
|
| 139 |
+
"d": "24 head"
|
| 140 |
+
},
|
| 141 |
+
"đáp án": "12 head"
|
| 142 |
+
},
|
| 143 |
+
"15": {
|
| 144 |
+
"câu hỏi": "Theo nội dung, BERT được huấn luyện trước bằng hai nhiệm vụ nào?",
|
| 145 |
+
"lựa chọn": {
|
| 146 |
+
"a": "Masked Language Modeling và Next Sentence Prediction",
|
| 147 |
+
"b": "Sentiment Analysis và Text Summarization",
|
| 148 |
+
"c": "Machine Translation và Question Answering",
|
| 149 |
+
"d": "Named Entity Recognition và Part-of-Speech Tagging"
|
| 150 |
+
},
|
| 151 |
+
"đáp án": "Masked Language Modeling và Next Sentence Prediction"
|
| 152 |
+
},
|
| 153 |
+
"16": {
|
| 154 |
+
"câu hỏi": "Theo bảng tổng hợp, câu nào thuộc nhóm \"lottery_phrases\"?",
|
| 155 |
+
"lựa chọn": {
|
| 156 |
+
"a": "“Flash sale ends tonight – 30% of all items!”",
|
| 157 |
+
"b": "“You’ve been selected for a loyalty reward.”",
|
| 158 |
+
"c": "“Unusual login detected. Was this you?”",
|
| 159 |
+
"d": "“Act now to secure your spot in the seminar.”"
|
| 160 |
+
},
|
| 161 |
+
"đáp án": "“You’ve been selected for a loyalty reward.”"
|
| 162 |
+
},
|
| 163 |
+
"17": {
|
| 164 |
+
"câu hỏi": "Theo nội dung, một nhược điểm của phương pháp dựa trên từ khóa trong việc phát hiện spam là gì?",
|
| 165 |
+
"lựa chọn": {
|
| 166 |
+
"a": "Có thể xử lý linh hoạt các biến thể từ và lỗi chính tả.",
|
| 167 |
+
"b": "Thiếu linh hoạt, không thể xử lý các biến thể từ và lỗi chính tả.",
|
| 168 |
+
"c": "Hiểu ngữ cảnh, phân biệt đúng từ 'free' trong các câu khác nhau.",
|
| 169 |
+
"d": "Sử dụng embedding ngữ cảnh sâu như BERT để nắm bắt ý nghĩa."
|
| 170 |
+
},
|
| 171 |
+
"đáp án": "Thiếu linh hoạt, không thể xử lý các biến thể từ và lỗi chính tả."
|
| 172 |
+
},
|
| 173 |
+
"18": {
|
| 174 |
+
"câu hỏi": "Theo nội dung trên, một nhược điểm chính của các mô hình ngôn ngữ lớn là gì?",
|
| 175 |
+
"lựa chọn": {
|
| 176 |
+
"a": "Yêu cầu tài nguyên tính toán lớn, bao gồm thời gian và chi phí huấn luyện và fine‑tuning.",
|
| 177 |
+
"b": "Có khả năng giải thích quyết định dự đoán một cách rõ ràng và trực quan.",
|
| 178 |
+
"c": "Có thể học được ranh giới phân biệt tốt hơn khi tăng cường dữ liệu.",
|
| 179 |
+
"d": "Cho phép phân loại nhanh chóng với độ chính xác cao ở k = 1."
|
| 180 |
+
},
|
| 181 |
+
"đáp án": "Yêu cầu tài nguyên tính toán lớn, bao gồm thời gian và chi phí huấn luyện và fine‑tuning."
|
| 182 |
+
},
|
| 183 |
+
"19": {
|
| 184 |
+
"câu hỏi": "Trong phương pháp Weighted KNN được mô tả, yếu tố nào được sử dụng làm trọng số để ưu tiên các láng giềng gần hơn?",
|
| 185 |
+
"lựa chọn": {
|
| 186 |
+
"a": "Độ lệch chuẩn",
|
| 187 |
+
"b": "Điểm tương đồng (similarity score)",
|
| 188 |
+
"c": "Khoảng cách Euclid",
|
| 189 |
+
"d": "Số lượng láng giềng"
|
| 190 |
+
},
|
| 191 |
+
"đáp án": "Điểm tương đồng (similarity score)"
|
| 192 |
+
},
|
| 193 |
+
"20": {
|
| 194 |
+
"câu hỏi": "Trong phương pháp kết hợp điểm ngữ nghĩa BERT và điểm từ khóa để đưa ra quyết định cuối cùng, trọng số được gán cho mỗi loại điểm là bao nhiêu?",
|
| 195 |
+
"lựa chọn": {
|
| 196 |
+
"a": "0.5 BERT và 0.5 từ khóa",
|
| 197 |
+
"b": "0.7 BERT và 0.3 từ khóa",
|
| 198 |
+
"c": "0.6 BERT và 0.4 từ khóa",
|
| 199 |
+
"d": "0.8 BERT và 0.2 từ khóa"
|
| 200 |
+
},
|
| 201 |
+
"đáp án": "0.7 BERT và 0.3 từ khóa"
|
| 202 |
+
}
|
| 203 |
+
},
|
| 204 |
+
"validation": {
|
| 205 |
+
"1": {
|
| 206 |
+
"supported_by_embeddings": true,
|
| 207 |
+
"max_similarity": 0.9192600250244141,
|
| 208 |
+
"evidence": [
|
| 209 |
+
{
|
| 210 |
+
"idx": 41,
|
| 211 |
+
"page": 19,
|
| 212 |
+
"score": 0.7189286947250366,
|
| 213 |
+
"text": "Đối với điểm truy vấn _q_, KNN truyền thống tính toán:\n\n\nˆ\n_y_ = arg max _c_ _i_ _∈C_ _[|{][x]_ _[j]_ _[ ∈N]_ _[K]_ [(] _[q]_ [) :] _[ y]_ [(] _[x]_ _[j]_ [) =] _[ c]_ _[i]_ _[}|]_ (1)\n\n\n**Phân tích Bias:**\nXác suất đểmột K-neighborhood ngẫu nhiên chứa _k_ thực thểtừlớp _c_ _i_ tuân theo phân phối siêu hình\nhọc:\n\n\n19"
|
| 214 |
+
},
|
| 215 |
+
{
|
| 216 |
+
"idx": 8,
|
| 217 |
+
"page": 23,
|
| 218 |
+
"score": 0.7741187810897827,
|
| 219 |
+
"text": "**Chứng minh tính chất 2 (Bịchặn):**\nTheo bất đẳng thức Cauchy-Schwarz:\n\n\n_|x_ _j_ _· q| ≤∥x_ _j_ _∥× ∥q∥_ (29)\n\n\nChia cảhai vếcho _∥x_ _j_ _∥× ∥q∥_ (giảsử _x_ _j_ _, q ̸_ = 0):\n\n\n\n_x_ _j_ _·_ _q_\n���� _∥x_ _j_ _∥× ∥q∥_\n\n\n\n_≤_ 1 (30)\n����\n\n\n\nĐiều này có nghĩa là:\n\n\nDấu bằng xảy ra khi:\n\n\n\n_−_ 1 _≤_ _K_ cos ( _x_ _j_ _, q_ ) _≤_ 1 (31)\n\n\n\n\n - _K_ cos ( _x_ _j_ _, q_ ) = 1 nếu _x_ _j_ và _q_ cùng hướng: _x_ _j_ = _c · q_ với _c >_ 0\n\n\n - _K_ cos ( _x_ _j_ _, q_ ) = _−_ 1 nếu _x_ _j_ và _q_ ngược hướng: _x_ _j_ = _c · q_ với _c <_ 0\n\n\n - _K_ cos ( _x_ _j_ _, q_ ) = 0 nếu _x_ _j_ và _q_ vuông góc: _x_ _j_ _⊥_ _q_\n\n\n**Chứng minh tính chất 3 (Chuẩn hóa - Không đổi với độlớn vector):**\nXét hai vector _x_ _[′]_ _j_ [=] _[ λx]_ _[j]_ [ và] _[ q]_ _[′]_ [ =] _[ µq]_ [ với] _[ λ, µ >]_ [ 0][:]\n\n\n23"
|
| 220 |
+
},
|
| 221 |
+
{
|
| 222 |
+
"idx": 56,
|
| 223 |
+
"page": 24,
|
| 224 |
+
"score": 0.9192600250244141,
|
| 225 |
+
"text": "**6.4.3** **Trọng sốNội dung dựa trên Saliency**\n\n\n**Định nghĩa 3** (Gradient-based Saliency) **.** _Thành phần saliency nắm bắt_ _**tầm quan trọng cụthể**_\n_**theo đầu vào**_ _dựa trên mô hình explainable AI:_\n\n\n_saliency_ ( _x_ _j_ _, q_ ) = _∥∇_ _x_ _j_ _L_ ( _f_ ( _x_ _j_ ) _,_ ˆ _y_ ) _∥_ 2 (38)\n\n\n**6.4.4** **Kết hợp Lồi và Tham sốCân bằng** _α_\n\n\n**Định lý 6.1** (Tính chất Convex Combination) **.** _Tham số_ _α tạo ra_ _**kết hợp lồi**_ _của hai lược đồtrọng_\n_số:_\n\n_weight_ = (1 _−_ _α_ ) _× w_ _similarity×ICF_ + _α × w_ _saliency_ (39)\n\n_Với α ∈_ [0 _,_ 1] _, kết quảnằm trong convex hull của hai thành phần._\n\n\n**6.5** **Phân tích Lý thuyết: Tại sao Công thức này Hợp lý**\n\n\n**6.5.1** **Phân tích Hiệu chỉnh Bias**\n\n\n**Định lý 6.2** (Bias Correction) **.** _Đối với majority voting truyền thống, ảnh hưởng kỳvọng của lớp c_ _i_ _là:_\n\nE[ _Influence_ _traditional_ ( _c_ _i_ )] = _K × P_ ( _c_ _i_ ) = _K ×_ _N_ _[n]_ _[i]_ (40)\n\n\n_Với phương pháp trọng sốcủa chúng ta:_\n\n\nE[ _Influence..."
|
| 226 |
+
}
|
| 227 |
+
],
|
| 228 |
+
"model_verdict": null
|
| 229 |
+
},
|
| 230 |
+
"2": {
|
| 231 |
+
"supported_by_embeddings": true,
|
| 232 |
+
"max_similarity": 0.7949658036231995,
|
| 233 |
+
"evidence": [
|
| 234 |
+
{
|
| 235 |
+
"idx": 21,
|
| 236 |
+
"page": 15,
|
| 237 |
+
"score": 0.5949141979217529,
|
| 238 |
+
"text": "Trong bài toán spam/ham, BERT được tinh\nchỉnh đểtối ưu hóa dựđoán nhãn và tập trung vào các từkhóa quan trọng như “miễn phí” hoặc “quà\ntặng” trong tin nhắn spam. **Ứng dụng** : Trong phân loại tin nhắn spam/ham, BERT chuyển tin nhắn thành vector số, hiểu ngữ\ncảnh sâu sắc (ví dụ: nhận diện ”miễn phí” trong ngữcảnh quảng cáo), và dựđoán nhãn (spam hoặc\nham). **Ưu điểm** :\n\n\n - Hiểu ngữcảnh hai chiều, vượt trội so với các phương pháp truyền thống như TF-IDF. - Sửdụng vector [CLS] đểtổng hợp thông tin toàn câu, phù hợp cho phân loại. **5.3** **Kiến trúc BERT**\n\n\nQuy trình xửlý của BERT bao gồm ba giai đoạn chính:\n\n\n1. **Mã hóa đầu vào** : Chuyển tin nhắn thành token, embedding, và attention mask. 2. **Xửlý qua Transformer encoder** : Tạo biểu diễn ngữcảnh cho từng token, đặc biệt là vector\n\n[CLS]. 3. **Phân loại** : Sửdụng vector [CLS] đểdựđoán nhãn spam/ham. Phần này trình bày chi tiết từng thành phần của kiến trúc BERT và cách chúng hỗtrợbài toán phân\nloại tin nhắn spam/ham. **5.3.1** *..."
|
| 239 |
+
},
|
| 240 |
+
{
|
| 241 |
+
"idx": 52,
|
| 242 |
+
"page": 11,
|
| 243 |
+
"score": 0.7382397651672363,
|
| 244 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n\n - 2039 mẫu _hard spam_ : được tạo ra đểtăng sốlượng và độphức tạp của các tin nhắn spam, giúp\nmô hình nhận diện tốt hơn các biến thểcủa spam. - 815 mẫu _hard ham_ : là những tin nhắn hợp lệnhưng có chứa từkhóa gần giống spam, buộc mô\nhình phải học cách phân biệt tinh vi hơn giữa hai lớp. - 1053 mẫu được sinh ra bằng kỹthuật _synonym replacement_ (thay thếtừđồng nghĩa), giúp tăng\nsựđa dạng vềmặt ngôn ngữcho cảhai lớp. Kết quảlà một dataset dùng đểphân loại có kích thước 9479 mẫu gồm 6556 mẫu Ham, 2923 mẫu Spam\ncó phân phối cân bằng hơn, tạo nền tảng vững chắc cho việc huấn luyện mô hình phân loại hiệu quả. **Phương pháp**\n\n\nĐểđạt được mục tiêu trên, nhóm mình đã thiết kếmột hệthống data augmentation chuyên biệt, kết\nhợp giữa kỹthuật sinh dữliệu bằng mô hình ngôn ngữlớn (LLM), thay thếtừđồng nghĩa, và khung\nsinh câu theo kịch bản có kiểm soát. Hệthống gồm ba giai đoạn chính:\n\n\n1."
|
| 245 |
+
},
|
| 246 |
+
{
|
| 247 |
+
"idx": 64,
|
| 248 |
+
"page": 27,
|
| 249 |
+
"score": 0.7949658036231995,
|
| 250 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n## **7 Semi-supervised đểphân loại sub-category của spam**\n\n\n**7.1** **Vấn đề”Spam” không chỉlà ”Spam”**\n\n\nKhi đối mặt với vấn đềspam, việc phân loại nhịphân (binary classification) thành hai loại ”spam” và\n”không spam” (ham) là chưa đủđểxây dựng một hệthống phòng chống hiệu quả. Bản chất của tin\nnhắn spam đã thay đổi và trởnên đa dạng hơn rất nhiều. Việc coi tất cảcác tin nhắn spam như nhau sẽ\nbỏqua những sắc thái quan trọng, dẫn đến việc chúng ta không thểđưa ra các biện pháp xửlý phù hợp. Khi phân tích sâu hơn, chúng ta thấy rằng spam có thểđược chia thành nhiều **thểloại con (sub-**\n**category) khác nhau**, mỗi loại có mục tiêu và phương thức hoạt động riêng biệt:\n\n\n **Spam quảng cáo** (Promotional Spam): Nhằm mục đích tiếp thịsản phẩm, dịch vụ, các chương\ntrình khuyến mãi, giảm giá, hoặc các thông báo trúng thưởng. Đặc điểm của loại này là thường\nchứa các từkhóa liên quan đến mua sắm, giá cả, ưu đãi..."
|
| 251 |
+
}
|
| 252 |
+
],
|
| 253 |
+
"model_verdict": null
|
| 254 |
+
},
|
| 255 |
+
"3": {
|
| 256 |
+
"supported_by_embeddings": true,
|
| 257 |
+
"max_similarity": 0.5782788991928101,
|
| 258 |
+
"evidence": [
|
| 259 |
+
{
|
| 260 |
+
"idx": 52,
|
| 261 |
+
"page": 11,
|
| 262 |
+
"score": 0.5782788991928101,
|
| 263 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n\n - 2039 mẫu _hard spam_ : được tạo ra đểtăng sốlượng và độphức tạp của các tin nhắn spam, giúp\nmô hình nhận diện tốt hơn các biến thểcủa spam. - 815 mẫu _hard ham_ : là những tin nhắn hợp lệnhưng có chứa từkhóa gần giống spam, buộc mô\nhình phải học cách phân biệt tinh vi hơn giữa hai lớp. - 1053 mẫu được sinh ra bằng kỹthuật _synonym replacement_ (thay thếtừđồng nghĩa), giúp tăng\nsựđa dạng vềmặt ngôn ngữcho cảhai lớp. Kết quảlà một dataset dùng đểphân loại có kích thước 9479 mẫu gồm 6556 mẫu Ham, 2923 mẫu Spam\ncó phân phối cân bằng hơn, tạo nền tảng vững chắc cho việc huấn luyện mô hình phân loại hiệu quả. **Phương pháp**\n\n\nĐểđạt được mục tiêu trên, nhóm mình đã thiết kếmột hệthống data augmentation chuyên biệt, kết\nhợp giữa kỹthuật sinh dữliệu bằng mô hình ngôn ngữlớn (LLM), thay thếtừđồng nghĩa, và khung\nsinh câu theo kịch bản có kiểm soát. Hệthống gồm ba giai đoạn chính:\n\n\n1."
|
| 264 |
+
}
|
| 265 |
+
],
|
| 266 |
+
"model_verdict": null
|
| 267 |
+
},
|
| 268 |
+
"4": {
|
| 269 |
+
"supported_by_embeddings": true,
|
| 270 |
+
"max_similarity": 0.7534276247024536,
|
| 271 |
+
"evidence": [
|
| 272 |
+
{
|
| 273 |
+
"idx": 21,
|
| 274 |
+
"page": 15,
|
| 275 |
+
"score": 0.7180466651916504,
|
| 276 |
+
"text": "Trong bài toán spam/ham, BERT được tinh\nchỉnh đểtối ưu hóa dựđoán nhãn và tập trung vào các từkhóa quan trọng như “miễn phí” hoặc “quà\ntặng” trong tin nhắn spam. **Ứng dụng** : Trong phân loại tin nhắn spam/ham, BERT chuyển tin nhắn thành vector số, hiểu ngữ\ncảnh sâu sắc (ví dụ: nhận diện ”miễn phí” trong ngữcảnh quảng cáo), và dựđoán nhãn (spam hoặc\nham). **Ưu điểm** :\n\n\n - Hiểu ngữcảnh hai chiều, vượt trội so với các phương pháp truyền thống như TF-IDF. - Sửdụng vector [CLS] đểtổng hợp thông tin toàn câu, phù hợp cho phân loại. **5.3** **Kiến trúc BERT**\n\n\nQuy trình xửlý của BERT bao gồm ba giai đoạn chính:\n\n\n1. **Mã hóa đầu vào** : Chuyển tin nhắn thành token, embedding, và attention mask. 2. **Xửlý qua Transformer encoder** : Tạo biểu diễn ngữcảnh cho từng token, đặc biệt là vector\n\n[CLS]. 3. **Phân loại** : Sửdụng vector [CLS] đểdựđoán nhãn spam/ham. Phần này trình bày chi tiết từng thành phần của kiến trúc BERT và cách chúng hỗtrợbài toán phân\nloại tin nhắn spam/ham. **5.3.1** *..."
|
| 277 |
+
},
|
| 278 |
+
{
|
| 279 |
+
"idx": 64,
|
| 280 |
+
"page": 27,
|
| 281 |
+
"score": 0.7191596031188965,
|
| 282 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n## **7 Semi-supervised đểphân loại sub-category của spam**\n\n\n**7.1** **Vấn đề”Spam” không chỉlà ”Spam”**\n\n\nKhi đối mặt với vấn đềspam, việc phân loại nhịphân (binary classification) thành hai loại ”spam” và\n”không spam” (ham) là chưa đủđểxây dựng một hệthống phòng chống hiệu quả. Bản chất của tin\nnhắn spam đã thay đổi và trởnên đa dạng hơn rất nhiều. Việc coi tất cảcác tin nhắn spam như nhau sẽ\nbỏqua những sắc thái quan trọng, dẫn đến việc chúng ta không thểđưa ra các biện pháp xửlý phù hợp. Khi phân tích sâu hơn, chúng ta thấy rằng spam có thểđược chia thành nhiều **thểloại con (sub-**\n**category) khác nhau**, mỗi loại có mục tiêu và phương thức hoạt động riêng biệt:\n\n\n **Spam quảng cáo** (Promotional Spam): Nhằm mục đích tiếp thịsản phẩm, dịch vụ, các chương\ntrình khuyến mãi, giảm giá, hoặc các thông báo trúng thưởng. Đặc điểm của loại này là thường\nchứa các từkhóa liên quan đến mua sắm, giá cả, ưu đãi..."
|
| 283 |
+
},
|
| 284 |
+
{
|
| 285 |
+
"idx": 1,
|
| 286 |
+
"page": 5,
|
| 287 |
+
"score": 0.7534276247024536,
|
| 288 |
+
"text": "Điều này đặc biệt quan trọng\ntrong các hệthống chống spam hiện đại, giúp người dùng hiểu rõ liệu một email nên bịxóa, xem qua\nhay báo cáo. Ngoài ra, nhóm còn hướng đến việc **mởrộng phân loại chi tiết trong nhóm spam**\n(quảng cáo, hệthống, lừa đảo, v.v...) nhằm tăng trải nghiệm và bảo mật cho người dùng. Hệthống phân loại tin nhắn spam/ham được thiết kếvới cơ chếđầu vào – đầu ra như sau:\n\n\n\n\n\n5"
|
| 289 |
+
}
|
| 290 |
+
],
|
| 291 |
+
"model_verdict": null
|
| 292 |
+
},
|
| 293 |
+
"5": {
|
| 294 |
+
"supported_by_embeddings": true,
|
| 295 |
+
"max_similarity": 0.7267791032791138,
|
| 296 |
+
"evidence": [
|
| 297 |
+
{
|
| 298 |
+
"idx": 60,
|
| 299 |
+
"page": 10,
|
| 300 |
+
"score": 0.6037057638168335,
|
| 301 |
+
"text": "Đểgiải quyết vấn đềnày, dataset đã được tăng cường đáng kểbằng cách sửdụng một mô hình học sâu\nđểtạo ra các mẫu mới:\n\n\n10"
|
| 302 |
+
},
|
| 303 |
+
{
|
| 304 |
+
"idx": 3,
|
| 305 |
+
"page": 28,
|
| 306 |
+
"score": 0.7101945281028748,
|
| 307 |
+
"text": "**–**\nNhờđó, mô hình có thểhiểu được sựkhác biệt tinh tếgiữa các cách diễn đạt, xửlý được\ncác từđồng nghĩa và các biến thểngôn ngữ. **Nhược điểm:**\n\n\n**– Đòi hỏi tài nguyên tính toán lớn:** Việc huấn luyện và fine-tuning các mô hình này cần\nnhiều thời gian và chi phí. **– Phức tạp:** Việc fine-tuning cho từng tác vụcụthểcó thểphức tạp. Đặc biệt, nếu không có\nđủdữliệu đã được gán nhãn, hiệu quảcủa các mô hình này sẽbịhạn chế. **7.3** **Phương pháp Semi-supervised sub-category của spam**\n\n\nĐểtận dụng ưu điểm của 2 phương pháp phân loại sub-category phần trên. Chúng tôi đềxuất thực\nhiện một phương pháp semi-supervised bằng cách kết hợp bert embeđings với nối từkhóa. Phương pháp này được gọi là ”bán giám sát” vì nó sửdụng một lượng nhỏdữliệu có nhãn (reference_texts\nvà category_keywords) đểphân loại một lượng lớn dữliệu chưa có nhãn (spam_texts). Tiến trình thực hiện của phương pháp như sau:\n\n\n1. **Bước 1: BERT embeddings**\n\n\n **Tạo Embeddings của Văn bản Spam:** đểbiến mỗi tin nhắn spam ..."
|
| 308 |
+
},
|
| 309 |
+
{
|
| 310 |
+
"idx": 61,
|
| 311 |
+
"page": 26,
|
| 312 |
+
"score": 0.7267791032791138,
|
| 313 |
+
"text": "Những cải thiện này đến từcác yếu tốsau:\n\n\n **Tăng cường dữliệu:** sinh thêm mẫu khó và thay từđồng nghĩa giúp đa dạng hóa ngữcảnh và\nlàm mô hình học được ranh giới phân biệt tốt hơn. **Tập huấn luyện lớn hơn:** từdưới 1.000 mẫu lên hơn 9.000 mẫu giúp mô hình tổng quát hóa\ntốt hơn. **Tập trung vào mẫu khó:** ưu tiên những ví dụgần ranh giới giữa spam/ham nhằm tăng tính\nphân biệt cho mô hình. **Kết luận:** Mô hình mới không chỉđạt hiệu suất cao ở _k_ = 5 mà còn cải thiện đáng kểở _k_ = 1, rất hữu\ních cho các ứng dụng yêu cầu tốc độsuy luận nhanh mà vẫn đảm bảo độchính xác cao. 26"
|
| 314 |
+
}
|
| 315 |
+
],
|
| 316 |
+
"model_verdict": null
|
| 317 |
+
},
|
| 318 |
+
"6": {
|
| 319 |
+
"supported_by_embeddings": true,
|
| 320 |
+
"max_similarity": 1.1316804885864258,
|
| 321 |
+
"evidence": [
|
| 322 |
+
{
|
| 323 |
+
"idx": 3,
|
| 324 |
+
"page": 28,
|
| 325 |
+
"score": 0.8143035769462585,
|
| 326 |
+
"text": "**–**\nNhờđó, mô hình có thểhiểu được sựkhác biệt tinh tếgiữa các cách diễn đạt, xửlý được\ncác từđồng nghĩa và các biến thểngôn ngữ. **Nhược điểm:**\n\n\n**– Đòi hỏi tài nguyên tính toán lớn:** Việc huấn luyện và fine-tuning các mô hình này cần\nnhiều thời gian và chi phí. **– Phức tạp:** Việc fine-tuning cho từng tác vụcụthểcó thểphức tạp. Đặc biệt, nếu không có\nđủdữliệu đã được gán nhãn, hiệu quảcủa các mô hình này sẽbịhạn chế. **7.3** **Phương pháp Semi-supervised sub-category của spam**\n\n\nĐểtận dụng ưu điểm của 2 phương pháp phân loại sub-category phần trên. Chúng tôi đềxuất thực\nhiện một phương pháp semi-supervised bằng cách kết hợp bert embeđings với nối từkhóa. Phương pháp này được gọi là ”bán giám sát” vì nó sửdụng một lượng nhỏdữliệu có nhãn (reference_texts\nvà category_keywords) đểphân loại một lượng lớn dữliệu chưa có nhãn (spam_texts). Tiến trình thực hiện của phương pháp như sau:\n\n\n1. **Bước 1: BERT embeddings**\n\n\n **Tạo Embeddings của Văn bản Spam:** đểbiến mỗi tin nhắn spam ..."
|
| 327 |
+
},
|
| 328 |
+
{
|
| 329 |
+
"idx": 61,
|
| 330 |
+
"page": 26,
|
| 331 |
+
"score": 0.9040168523788452,
|
| 332 |
+
"text": "Những cải thiện này đến từcác yếu tốsau:\n\n\n **Tăng cường dữliệu:** sinh thêm mẫu khó và thay từđồng nghĩa giúp đa dạng hóa ngữcảnh và\nlàm mô hình học được ranh giới phân biệt tốt hơn. **Tập huấn luyện lớn hơn:** từdưới 1.000 mẫu lên hơn 9.000 mẫu giúp mô hình tổng quát hóa\ntốt hơn. **Tập trung vào mẫu khó:** ưu tiên những ví dụgần ranh giới giữa spam/ham nhằm tăng tính\nphân biệt cho mô hình. **Kết luận:** Mô hình mới không chỉđạt hiệu suất cao ở _k_ = 5 mà còn cải thiện đáng kểở _k_ = 1, rất hữu\ních cho các ứng dụng yêu cầu tốc độsuy luận nhanh mà vẫn đảm bảo độchính xác cao. 26"
|
| 333 |
+
},
|
| 334 |
+
{
|
| 335 |
+
"idx": 60,
|
| 336 |
+
"page": 10,
|
| 337 |
+
"score": 1.1316804885864258,
|
| 338 |
+
"text": "Đểgiải quyết vấn đềnày, dataset đã được tăng cường đáng kểbằng cách sửdụng một mô hình học sâu\nđểtạo ra các mẫu mới:\n\n\n10"
|
| 339 |
+
}
|
| 340 |
+
],
|
| 341 |
+
"model_verdict": null
|
| 342 |
+
},
|
| 343 |
+
"7": {
|
| 344 |
+
"supported_by_embeddings": true,
|
| 345 |
+
"max_similarity": 0.9357913732528687,
|
| 346 |
+
"evidence": [
|
| 347 |
+
{
|
| 348 |
+
"idx": 18,
|
| 349 |
+
"page": 7,
|
| 350 |
+
"score": 0.7424218058586121,
|
| 351 |
+
"text": "Tham số _α_ là tham sốđiều chỉnh, quyết định mức độưu tiên của điểm saliency so với độ\ntương đồng tổng thểcủa tin nhắn. - **Vote Scores:** Hệthống hiển thịđiểm sốbỏphiếu cho mỗi lớp ( _Ham_ và _Spam_ ). Dựđoán cuối\ncùng sẽlà lớp có điểm sốcao nhất. - **Spam Subcategory:** Nếu tin nhắn được phân loại là _SPAM_, hệthống tiếp tục phân tích đểxác\nđịnh tiểu mục spam cụthể(ví dụ: _spam_quangcao_, _spam_hethong_ ). **Cơ sởgiải thích (Top neighbors):** Hệthống liệt kê một sốhàng xóm gần nhất trong cơ sởdữ\nliệu vector. Mỗi neighbors bao gồm:\n\n\n**–** _Nhãn (Label):_ Nhãn của tin nhắn gốc ( _ham_ hoặc _spam_ ). **–**\n_Độtương đồng (Similarity):_ Giá trịthểhiện mức độtương đồng giữa tin nhắn đầu vào và\nhàng xóm. **–**\n_Nội dung (Message):_ Nội dung của tin nhắn hàng xóm. 7"
|
| 352 |
+
},
|
| 353 |
+
{
|
| 354 |
+
"idx": 11,
|
| 355 |
+
"page": 29,
|
| 356 |
+
"score": 0.909127414226532,
|
| 357 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n\n **Tính Độtương đồng Ngữnghĩa:** Đối với mỗi tin nhắn spam, thuật toán tính toán độ\ntương đồng cosine giữa embedding của tin nhắn đó và embedding của từng điểm neo tham\nchiếu. Kết quảlà một điểm số( _bert_scores_ ) cho thấy mức độliên quan vềmặt ngữnghĩa\ncủa tin nhắn với từng tiểu thểloại. 2. **Bước 2: Keyword matching**\n\n\n **Định nghĩa Từkhóa:** tạo một danh sách từkhóa chi tiết cho từng thểloại con. - **Tính Điểm Từkhóa:** Với mỗi tin nhắn, đoạn mã s���đếm sốlượng từkhóa trong danh sách\nxuất hiện. Điểm sốnày được chuẩn hóa.( _keyword_scores_ ) đểso sánh công bằng giữa các thể\nloại con có sốlượng từkhóa khác nhau. 3. **Bước 3: combine và ra quyết định** Đây là bước then chốt của phương pháp lai này. **Kết hợp có trọng số:** Mô hình kết hợp hai điểm sốtrên bằng cách sửdụng trọng số. Với\nđiểm ngữnghĩa của BERT chiếm 70% và điểm từkhóa chiếm 30% (0 _._ 7 _×_ bert_scores +0 _._ 3 _×_\nkeyword_scores). Sựkết hợp này tận dụng khảnăng hiểu ngữnghĩa sâu củ..."
|
| 358 |
+
},
|
| 359 |
+
{
|
| 360 |
+
"idx": 68,
|
| 361 |
+
"page": 13,
|
| 362 |
+
"score": 0.9357913732528687,
|
| 363 |
+
"text": "Trong trường hợp này, phép nhân vô hướng (Inner Product) mà\nIndexFlatIP sửdụng sẽcho kết quảtương đương với độtương đồng cosine. Độtương đồng cosine\nlà thước đo tiêu chuẩn đểđánh giá sựtương đồng ngữnghĩa trong các bài toán NLP. Do đó,\nIndexFlatIP là lựa chọn hoàn hảo đểtruy vấn các tin nhắn có ý nghĩa tương tự, tạo ra một hệ\nthống tìm kiếm ngữnghĩa hiệu quảvà chính xác. ## **4 Explainable AI: Masking-based saliency heat map**\n\n\nNhận thấy rằng toàn bộhệthống phân loại sửdụng mô hình embedding E5 kết hợp với cơ sởdữliệu\nFAISS đểtruy vấn và tìm kiếm `k` tin nhắn gần nhất là một mô hình dạng “hộp đen” (black-box), nên\nnhóm đặt mục tiêu tăng tính giải thích của mô hình bằng cách chỉra cụthểnhững token nào trong\ncâu đầu vào thực sựảnh hưởng đến embedding câu, từđó dẫn đến quyết định phân loại. Ý tưởng cụ\nthểlà trực quan hóa mức độđóng góp của từng token bằng bản đồnhiệt (heatmap) — token nào càng\nđóng góp nhiều thì sẽđược tô màu đậm hơn. Do nhóm tập trung chủyếu vào việc phân loại và giải t..."
|
| 364 |
+
}
|
| 365 |
+
],
|
| 366 |
+
"model_verdict": null
|
| 367 |
+
},
|
| 368 |
+
"8": {
|
| 369 |
+
"supported_by_embeddings": true,
|
| 370 |
+
"max_similarity": 0.610893189907074,
|
| 371 |
+
"evidence": [
|
| 372 |
+
{
|
| 373 |
+
"idx": 1,
|
| 374 |
+
"page": 5,
|
| 375 |
+
"score": 0.5394615530967712,
|
| 376 |
+
"text": "Điều này đặc biệt quan trọng\ntrong các hệthống chống spam hiện đại, giúp người dùng hiểu rõ liệu một email nên bịxóa, xem qua\nhay báo cáo. Ngoài ra, nhóm còn hướng đến việc **mởrộng phân loại chi tiết trong nhóm spam**\n(quảng cáo, hệthống, lừa đảo, v.v...) nhằm tăng trải nghiệm và bảo mật cho người dùng. Hệthống phân loại tin nhắn spam/ham được thiết kếvới cơ chếđầu vào – đầu ra như sau:\n\n\n\n\n\n5"
|
| 377 |
+
},
|
| 378 |
+
{
|
| 379 |
+
"idx": 64,
|
| 380 |
+
"page": 27,
|
| 381 |
+
"score": 0.5891628265380859,
|
| 382 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n## **7 Semi-supervised đểphân loại sub-category của spam**\n\n\n**7.1** **Vấn đề”Spam” không chỉlà ”Spam”**\n\n\nKhi đối mặt với vấn đềspam, việc phân loại nhịphân (binary classification) thành hai loại ”spam” và\n”không spam” (ham) là chưa đủđểxây dựng một hệthống phòng chống hiệu quả. Bản chất của tin\nnhắn spam đã thay đổi và trởnên đa dạng hơn rất nhiều. Việc coi tất cảcác tin nhắn spam như nhau sẽ\nbỏqua những sắc thái quan trọng, dẫn đến việc chúng ta không thểđưa ra các biện pháp xửlý phù hợp. Khi phân tích sâu hơn, chúng ta thấy rằng spam có thểđược chia thành nhiều **thểloại con (sub-**\n**category) khác nhau**, mỗi loại có mục tiêu và phương thức hoạt động riêng biệt:\n\n\n **Spam quảng cáo** (Promotional Spam): Nhằm mục đích tiếp thịsản phẩm, dịch vụ, các chương\ntrình khuyến mãi, giảm giá, hoặc các thông báo trúng thưởng. Đặc điểm của loại này là thường\nchứa các từkhóa liên quan đến mua sắm, giá cả, ưu đãi..."
|
| 383 |
+
},
|
| 384 |
+
{
|
| 385 |
+
"idx": 52,
|
| 386 |
+
"page": 11,
|
| 387 |
+
"score": 0.610893189907074,
|
| 388 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n\n - 2039 mẫu _hard spam_ : được tạo ra đểtăng sốlượng và độphức tạp của các tin nhắn spam, giúp\nmô hình nhận diện tốt hơn các biến thểcủa spam. - 815 mẫu _hard ham_ : là những tin nhắn hợp lệnhưng có chứa từkhóa gần giống spam, buộc mô\nhình phải học cách phân biệt tinh vi hơn giữa hai lớp. - 1053 mẫu được sinh ra bằng kỹthuật _synonym replacement_ (thay thếtừđồng nghĩa), giúp tăng\nsựđa dạng vềmặt ngôn ngữcho cảhai lớp. Kết quảlà một dataset dùng đểphân loại có kích thước 9479 mẫu gồm 6556 mẫu Ham, 2923 mẫu Spam\ncó phân phối cân bằng hơn, tạo nền tảng vững chắc cho việc huấn luyện mô hình phân loại hiệu quả. **Phương pháp**\n\n\nĐểđạt được mục tiêu trên, nhóm mình đã thiết kếmột hệthống data augmentation chuyên biệt, kết\nhợp giữa kỹthuật sinh dữliệu bằng mô hình ngôn ngữlớn (LLM), thay thếtừđồng nghĩa, và khung\nsinh câu theo kịch bản có kiểm soát. Hệthống gồm ba giai đoạn chính:\n\n\n1."
|
| 389 |
+
}
|
| 390 |
+
],
|
| 391 |
+
"model_verdict": null
|
| 392 |
+
},
|
| 393 |
+
"9": {
|
| 394 |
+
"supported_by_embeddings": true,
|
| 395 |
+
"max_similarity": 0.5543808341026306,
|
| 396 |
+
"evidence": [
|
| 397 |
+
{
|
| 398 |
+
"idx": 39,
|
| 399 |
+
"page": 4,
|
| 400 |
+
"score": 0.5543808341026306,
|
| 401 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n\n\n\n\n**Các lĩnh vực dễbịnhầm lẫn giữa spam và ham**\n\n\nTrong những năm gần đây, sựphát triển của công nghệemail marketing và các hình thức lừa đảo trực\ntuyến đã dẫn đến sựgia tăng mạnh mẽcủa các loại **spam tinh vi** – những tin nhắn rác được _thiết kế_\n_cẩn thận đểvượt qua các bộlọc tựđộng_ . Chúng thường sửdụng ngôn ngữlịch sự, cú pháp tựnhiên như\nemail thật, thậm chí mô phỏng cách viết của email công việc hoặc cá nhân. Cùng lúc đó, cũng tồn tại nhiều email hợp lệ( **ham** ) có chứa các từkhóa như _“transfer”_, _“discount”_,\n_“verify”_ vốn thường xuất hiện trong spam, khiến hệthống nhầm lẫn. Những trường hợp như vậy được\ngọi là **hard ham** – tức là các email hợp pháp nhưng có đặc điểm giống với spam. Vì vậy, các mô hình học máy nếu chỉdựa vào keyword hoặc kỹthuật phân loại đơn giản như TF-IDF,\nNaive Bayes,... sẽkhó đạt hiệu quảcao. Thay vào đó, mô hình cần có khảnăng **hiểu sâu ngữnghĩa**,\nkết hợp thông tin ngữcảnh, cú pháp, và thậm chí cảlịch sửng..."
|
| 402 |
+
}
|
| 403 |
+
],
|
| 404 |
+
"model_verdict": null
|
| 405 |
+
},
|
| 406 |
+
"10": {
|
| 407 |
+
"supported_by_embeddings": true,
|
| 408 |
+
"max_similarity": 0.5062772035598755,
|
| 409 |
+
"evidence": [
|
| 410 |
+
{
|
| 411 |
+
"idx": 64,
|
| 412 |
+
"page": 27,
|
| 413 |
+
"score": 0.5062772035598755,
|
| 414 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n## **7 Semi-supervised đểphân loại sub-category của spam**\n\n\n**7.1** **Vấn đề”Spam” không chỉlà ”Spam”**\n\n\nKhi đối mặt với vấn đềspam, việc phân loại nhịphân (binary classification) thành hai loại ”spam” và\n”không spam” (ham) là chưa đủđểxây dựng một hệthống phòng chống hiệu quả. Bản chất của tin\nnhắn spam đã thay đổi và trởnên đa dạng hơn rất nhiều. Việc coi tất cảcác tin nhắn spam như nhau sẽ\nbỏqua những sắc thái quan trọng, dẫn đến việc chúng ta không thểđưa ra các biện pháp xửlý phù hợp. Khi phân tích sâu hơn, chúng ta thấy rằng spam có thểđược chia thành nhiều **thểloại con (sub-**\n**category) khác nhau**, mỗi loại có mục tiêu và phương thức hoạt động riêng biệt:\n\n\n **Spam quảng cáo** (Promotional Spam): Nhằm mục đích tiếp thịsản phẩm, dịch vụ, các chương\ntrình khuyến mãi, giảm giá, hoặc các thông báo trúng thưởng. Đặc điểm của loại này là thường\nchứa các từkhóa liên quan đến mua sắm, giá cả, ưu đãi..."
|
| 415 |
+
}
|
| 416 |
+
],
|
| 417 |
+
"model_verdict": null
|
| 418 |
+
},
|
| 419 |
+
"11": {
|
| 420 |
+
"supported_by_embeddings": true,
|
| 421 |
+
"max_similarity": 0.7763429880142212,
|
| 422 |
+
"evidence": [
|
| 423 |
+
{
|
| 424 |
+
"idx": 14,
|
| 425 |
+
"page": 20,
|
| 426 |
+
"score": 0.7428227663040161,
|
| 427 |
+
"text": "**6.1** **Khung Phân loại Trọng sốĐềxuất**\n\n\nVì vậy nhóm đã nghiên cứu và đềxuất áp dụng công thức trọng sốmới trong quá trình voting của KNN\nbằng kết hợp hai yếu tốtương đồng (similarity) và tầm quan trọng tinh tếcủa từng thực thể(saliency). **6.2** **Công thức Cốt lõi**\n\n\nweight( _x_ _j_ _,_ _q_ ) = (1 _−_ _α_ ) _×_ similarity( _x_ _j_ _,_ _q_ ) _×_ ICF( _y_ ( _x_ _j_ )) + _α ×_ saliency( _x_ _j_ _,_ _q_ ) (5)\n\n\nTrong đó:\n\n\n_x_ _j_ _·_ _q_\nsimilarity( _x_ _j_ _, q_ ) = cos( _x_ _j_ _, q_ ) = (6)\n_∥x_ _j_ _∥× ∥q∥_\n\n\n\n_N_\nICF( _c_ _i_ ) =\n_M × n_ _i_\n\n\n\n(7)\n\n\n\nsaliency( _x_ _j_ _, q_ ) = _∥∇_ _x_ _j_ _L_ ( _f_ ( _x_ _j_ ) _,_ ˆ _y_ ) _∥_ 2 (8)\n\n_α ∈_ [0 _,_ 1] (tham sốcân bằng) (9)\n\n\n**6.3** **Quyết định Phân loại Cuối cùng**\n\n\n\nˆ\n_y_ = arg max\n_c_ _i_ _∈C_\n\n\n\n�\n\n_x_ _j_ _∈N_ _K_ ( _q_ )\n_y_ ( _x_ _j_ )= _c_ _i_\n\n\n20\n\n\n\nweight( _x_ _j_ _, q_ ) (10)"
|
| 428 |
+
},
|
| 429 |
+
{
|
| 430 |
+
"idx": 56,
|
| 431 |
+
"page": 24,
|
| 432 |
+
"score": 0.7464016675949097,
|
| 433 |
+
"text": "**6.4.3** **Trọng sốNội dung dựa trên Saliency**\n\n\n**Định nghĩa 3** (Gradient-based Saliency) **.** _Thành phần saliency nắm bắt_ _**tầm quan trọng cụthể**_\n_**theo đầu vào**_ _dựa trên mô hình explainable AI:_\n\n\n_saliency_ ( _x_ _j_ _, q_ ) = _∥∇_ _x_ _j_ _L_ ( _f_ ( _x_ _j_ ) _,_ ˆ _y_ ) _∥_ 2 (38)\n\n\n**6.4.4** **Kết hợp Lồi và Tham sốCân bằng** _α_\n\n\n**Định lý 6.1** (Tính chất Convex Combination) **.** _Tham số_ _α tạo ra_ _**kết hợp lồi**_ _của hai lược đồtrọng_\n_số:_\n\n_weight_ = (1 _−_ _α_ ) _× w_ _similarity×ICF_ + _α × w_ _saliency_ (39)\n\n_Với α ∈_ [0 _,_ 1] _, kết quảnằm trong convex hull của hai thành phần._\n\n\n**6.5** **Phân tích Lý thuyết: Tại sao Công thức này Hợp lý**\n\n\n**6.5.1** **Phân tích Hiệu chỉnh Bias**\n\n\n**Định lý 6.2** (Bias Correction) **.** _Đối với majority voting truyền thống, ảnh hưởng kỳvọng của lớp c_ _i_ _là:_\n\nE[ _Influence_ _traditional_ ( _c_ _i_ )] = _K × P_ ( _c_ _i_ ) = _K ×_ _N_ _[n]_ _[i]_ (40)\n\n\n_Với phương pháp trọng sốcủa chúng ta:_\n\n\nE[ _Influence..."
|
| 434 |
+
},
|
| 435 |
+
{
|
| 436 |
+
"idx": 48,
|
| 437 |
+
"page": 24,
|
| 438 |
+
"score": 0.7763429880142212,
|
| 439 |
+
"text": "]_ (43)\n\n_M_ _[×]_ [ E][[] _[similarity][ ×][ saliency]_ []]\n\n\n24"
|
| 440 |
+
}
|
| 441 |
+
],
|
| 442 |
+
"model_verdict": null
|
| 443 |
+
},
|
| 444 |
+
"12": {
|
| 445 |
+
"supported_by_embeddings": true,
|
| 446 |
+
"max_similarity": 0.8878604173660278,
|
| 447 |
+
"evidence": [
|
| 448 |
+
{
|
| 449 |
+
"idx": 47,
|
| 450 |
+
"page": 26,
|
| 451 |
+
"score": 0.7113279104232788,
|
| 452 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n## **Đánh giá và So sánh Mô hình**\n\n\n**Kết quảmô hình gốc (do TA cung cấp)**\n\n\nChúng tôi tiến hành đánh giá mô hình phân loại KNN ban đầu trên tập kiểm tra gồm 884 mẫu, với các\ngiá trị _k_ khác nhau. Kết quảđộchính xác như sau:\n\n|Giá trị k|Độ chính xác|Số mẫu lỗi|\n|---|---|---|\n|1<br>3<br>5|82.24%<br>88.91%<br>92.87%|157/884<br>98/884<br>63/884|\n\n\n\nBảng 3: Hiệu suất mô hình gốc trên tập kiểm tra\n\n\n**Kết quảmô hình cải tiến (do nhóm phát triển)**\n\n\nVới mô hình cải tiến, chúng tôi đã huấn luyện trên một tập dữliệu lớn hơn rất nhiều (9.400 mẫu), được\ntăng cường từtập dữliệu GDrive gốc thông qua kỹthuật tạo mẫu khó và thay thếtừđồng nghĩa. Kết\nquảđạt được như sau:\n\n|Giá trị k|Độ chính xác|\n|---|---|\n|1<br>3<br>5|86.96%<br>89.68%<br>92.20%|\n\n\n\nBảng 4: Hiệu suất mô hình cải tiến trên tập dữliệu mởrộng\n\n\n**Phân tích kết quả**\n\n\nMô hình cải tiến cho thấy sựvượt trội rõ rệt ởmọi mức _k_ :\n\n\n - Với _k_ = 1: tăng từ **82.24%** lên **86.96%** ( **+4.72%** ). - ..."
|
| 453 |
+
},
|
| 454 |
+
{
|
| 455 |
+
"idx": 9,
|
| 456 |
+
"page": 1,
|
| 457 |
+
"score": 0.8842895030975342,
|
| 458 |
+
"text": "25\n\n6.5.4 Phân tích Consistency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25\n6.6 Kết luận . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25\n\n\n1"
|
| 459 |
+
},
|
| 460 |
+
{
|
| 461 |
+
"idx": 14,
|
| 462 |
+
"page": 20,
|
| 463 |
+
"score": 0.8878604173660278,
|
| 464 |
+
"text": "**6.1** **Khung Phân loại Trọng sốĐềxuất**\n\n\nVì vậy nhóm đã nghiên cứu và đềxuất áp dụng công thức trọng sốmới trong quá trình voting của KNN\nbằng kết hợp hai yếu tốtương đồng (similarity) và tầm quan trọng tinh tếcủa từng thực thể(saliency). **6.2** **Công thức Cốt lõi**\n\n\nweight( _x_ _j_ _,_ _q_ ) = (1 _−_ _α_ ) _×_ similarity( _x_ _j_ _,_ _q_ ) _×_ ICF( _y_ ( _x_ _j_ )) + _α ×_ saliency( _x_ _j_ _,_ _q_ ) (5)\n\n\nTrong đó:\n\n\n_x_ _j_ _·_ _q_\nsimilarity( _x_ _j_ _, q_ ) = cos( _x_ _j_ _, q_ ) = (6)\n_∥x_ _j_ _∥× ∥q∥_\n\n\n\n_N_\nICF( _c_ _i_ ) =\n_M × n_ _i_\n\n\n\n(7)\n\n\n\nsaliency( _x_ _j_ _, q_ ) = _∥∇_ _x_ _j_ _L_ ( _f_ ( _x_ _j_ ) _,_ ˆ _y_ ) _∥_ 2 (8)\n\n_α ∈_ [0 _,_ 1] (tham sốcân bằng) (9)\n\n\n**6.3** **Quyết định Phân loại Cuối cùng**\n\n\n\nˆ\n_y_ = arg max\n_c_ _i_ _∈C_\n\n\n\n�\n\n_x_ _j_ _∈N_ _K_ ( _q_ )\n_y_ ( _x_ _j_ )= _c_ _i_\n\n\n20\n\n\n\nweight( _x_ _j_ _, q_ ) (10)"
|
| 465 |
+
}
|
| 466 |
+
],
|
| 467 |
+
"model_verdict": null
|
| 468 |
+
},
|
| 469 |
+
"13": {
|
| 470 |
+
"supported_by_embeddings": true,
|
| 471 |
+
"max_similarity": 0.8059824109077454,
|
| 472 |
+
"evidence": [
|
| 473 |
+
{
|
| 474 |
+
"idx": 14,
|
| 475 |
+
"page": 20,
|
| 476 |
+
"score": 0.5798600316047668,
|
| 477 |
+
"text": "**6.1** **Khung Phân loại Trọng sốĐềxuất**\n\n\nVì vậy nhóm đã nghiên cứu và đềxuất áp dụng công thức trọng sốmới trong quá trình voting của KNN\nbằng kết hợp hai yếu tốtương đồng (similarity) và tầm quan trọng tinh tếcủa từng thực thể(saliency). **6.2** **Công thức Cốt lõi**\n\n\nweight( _x_ _j_ _,_ _q_ ) = (1 _−_ _α_ ) _×_ similarity( _x_ _j_ _,_ _q_ ) _×_ ICF( _y_ ( _x_ _j_ )) + _α ×_ saliency( _x_ _j_ _,_ _q_ ) (5)\n\n\nTrong đó:\n\n\n_x_ _j_ _·_ _q_\nsimilarity( _x_ _j_ _, q_ ) = cos( _x_ _j_ _, q_ ) = (6)\n_∥x_ _j_ _∥× ∥q∥_\n\n\n\n_N_\nICF( _c_ _i_ ) =\n_M × n_ _i_\n\n\n\n(7)\n\n\n\nsaliency( _x_ _j_ _, q_ ) = _∥∇_ _x_ _j_ _L_ ( _f_ ( _x_ _j_ ) _,_ ˆ _y_ ) _∥_ 2 (8)\n\n_α ∈_ [0 _,_ 1] (tham sốcân bằng) (9)\n\n\n**6.3** **Quyết định Phân loại Cuối cùng**\n\n\n\nˆ\n_y_ = arg max\n_c_ _i_ _∈C_\n\n\n\n�\n\n_x_ _j_ _∈N_ _K_ ( _q_ )\n_y_ ( _x_ _j_ )= _c_ _i_\n\n\n20\n\n\n\nweight( _x_ _j_ _, q_ ) (10)"
|
| 478 |
+
},
|
| 479 |
+
{
|
| 480 |
+
"idx": 18,
|
| 481 |
+
"page": 7,
|
| 482 |
+
"score": 0.7496178150177002,
|
| 483 |
+
"text": "Tham số _α_ là tham sốđiều chỉnh, quyết định mức độưu tiên của điểm saliency so với độ\ntương đồng tổng thểcủa tin nhắn. - **Vote Scores:** Hệthống hiển thịđiểm sốbỏphiếu cho mỗi lớp ( _Ham_ và _Spam_ ). Dựđoán cuối\ncùng sẽlà lớp có điểm sốcao nhất. - **Spam Subcategory:** Nếu tin nhắn được phân loại là _SPAM_, hệthống tiếp tục phân tích đểxác\nđịnh tiểu mục spam cụthể(ví dụ: _spam_quangcao_, _spam_hethong_ ). **Cơ sởgiải thích (Top neighbors):** Hệthống liệt kê một sốhàng xóm gần nhất trong cơ sởdữ\nliệu vector. Mỗi neighbors bao gồm:\n\n\n**–** _Nhãn (Label):_ Nhãn của tin nhắn gốc ( _ham_ hoặc _spam_ ). **–**\n_Độtương đồng (Similarity):_ Giá trịthểhiện mức độtương đồng giữa tin nhắn đầu vào và\nhàng xóm. **–**\n_Nội dung (Message):_ Nội dung của tin nhắn hàng xóm. 7"
|
| 484 |
+
},
|
| 485 |
+
{
|
| 486 |
+
"idx": 33,
|
| 487 |
+
"page": 6,
|
| 488 |
+
"score": 0.8059824109077454,
|
| 489 |
+
"text": "**Similarity Search (KNN-Classifier):**\n\n\n **Vấn đềtồn đọng:** Phương pháp bỏphiếu đa số( _majority vote_ ) đơn giản trong KNN bỏqua\nmức độquan trọng của từng hàng xóm, nên các điểm ”xa” nhưng đông vẫn có thểáp đảo những\nđiểm ”gần” và ảnh hưởng sai lệch đến kết quảphân loại. **Giải pháp:** Khi có một tin nhắn mới, hệthống tìm kiếm những tin nhắn tương tựnhất. Quyết\nđịnh phân loại được đưa ra bằng Weighted KNN, sửdụng độtương đồng ( _similarity score_ ) làm\ntrọng sốđểưu tiên các hàng xóm gần hơn. 6"
|
| 490 |
+
}
|
| 491 |
+
],
|
| 492 |
+
"model_verdict": null
|
| 493 |
+
},
|
| 494 |
+
"14": {
|
| 495 |
+
"supported_by_embeddings": true,
|
| 496 |
+
"max_similarity": 1.1322075128555298,
|
| 497 |
+
"evidence": [
|
| 498 |
+
{
|
| 499 |
+
"idx": 53,
|
| 500 |
+
"page": 17,
|
| 501 |
+
"score": 0.6295226812362671,
|
| 502 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n\n**Cấu trúc** BERT-base có **12 lớp encoder**, mỗi lớp bao gồm:\n\n\n1. **Multi-Head Self-Attention** : Cho phép mỗi token “chú ý” đến các token khác trong chuỗi để\ncập nhật vector của nó. Công thức:\n\n\n\n_QK_ _T_\nAttention( _Q, K, V_ ) = softmax\n� ~~_√_~~ _d_ _k_\n\n\n\n_V_\n�\n\n\n\n\n - _Q_, _K_, _V_ : Ma trận query, key, value, được tạo từma trận embedding qua các trọng số _W_ _Q_,\n_W_ _K_, _W_ _V_ . - _d_ _k_ : Kích thước mỗi head (768 / 12 = 64). - Mỗi lớp có **12 head**, mỗi head xửlý một góc nhìn khác của ngữcảnh. Ví dụ: Trong “Nhận ngay quà tặng miễn phí!”, token “miễn” chú ý mạnh đến “quà” và “tặng”,\ntạo ngữcảnh quảng cáo. Attention Mask đảm bảo không chú ý đến [PAD]. Kết quả: Ma trận 16\n_×_ 768, với mỗi token được cập nhật dựa trên ngữcảnh. 2. **Residual Connection và Layer Normalization** : Cộng đầu vào và đầu ra của attention:\n\n\n_x_ + Attention( _x_ )\n\n\nSau đó chuẩn hóa:\nLayerNorm( _x_ + Attention( _x_ ))\n\n\n3. **Feed-Forward Neural Network (FFN)** : ..."
|
| 503 |
+
},
|
| 504 |
+
{
|
| 505 |
+
"idx": 50,
|
| 506 |
+
"page": 7,
|
| 507 |
+
"score": 1.0809839963912964,
|
| 508 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n\n**Explainable AI (XAI) và Classifier:**\n\n\n **Vấn đềtồn đọng:** Mô hình hoạt động như một ”hộp đen”, khó giải thích lý do đưa ra dựđoán. Khảnăng giải thích thường bịtách rời khỏi quá trình phân loại chính. **Giải pháp:** Tích hợp khảnăng giải thích vào lõi của bộphân loại. **–**\n_Masking-based Saliency:_ Phương pháp này xác định các từkhóa quan trọng nhất trong tin\nnhắn. Nói trực quan thì từnào quan trọng trong quyết định spam hơn sẽđược tô đậm hơn. **–**\n_Phân loại có tích hợp Saliency:_ Bộphân loại sửdụng một tham số‘alpha‘ đểđiều chỉnh mức\nđộảnh hưởng của điểm nổi bật (saliency score) vào công thức phân loại cuối cùng, giúp kết\nquảchính xác hơn và có thểgiải thích được. **Đầu ra cuối cùng:** Đầu ra cho mỗi câu gồm thông tin dựđoán và chỉsốgiải thích cho dựđoán đó,\ngiúp người dùng hiểu rõ quyết định của mô hình. Cấu trúc đầu ra bao gồm:\n\n\n - **Lớp dựđoán:** Tin nhắn được gán nhãn dựđoán cuối cùng ( _SPAM_ hoặc _HAM_ ) dựa trên kết quả\nphân loại. *..."
|
| 509 |
+
},
|
| 510 |
+
{
|
| 511 |
+
"idx": 54,
|
| 512 |
+
"page": 22,
|
| 513 |
+
"score": 1.1322075128555298,
|
| 514 |
+
"text": "Lấy ví dụđơn giản, giảsửchúng ta có một mã là một chuỗi nhịphân độdài 5, chẳng hạn như “ `10001` ”. Khi đó, lượng tin của mã này sẽlà 5 bit. Hình 3: Minh họa mối quan hệgiữa nội dung thông tin và tần suất lớp\n\n\nTừlý thuyết thông tin, nội dung thông tin của lớp _c_ _i_ là:\n\n\n\n_n_ _i_\n_I_ ( _c_ _i_ ) = _−_ log 2 ( _P_ ( _c_ _i_ )) = _−_ log 2\n� _N_\n\n\n\n(20)\n�\n\n\n\nICF của chúng ta tỷlệthuận với 2 _[I]_ [(] _[c]_ _[i]_ [)/][ log] [2] [(] _[N]_ [/] _[M]_ [)], có nghĩa là **các lớp hiếm hơn mang nhiều thông**\n**tin hơn** và nên nhận được trọng sốtỷlệcao hơn. **6.4.2** **Trọng sốKhoảng cách dựa trên Similarity**\n\n\n**Định nghĩa 2** (Cosine Similarity Kernel) **.** _Thành phần similarity đảm bảo rằng_ _**láng giềng gần hơn**_\n_**có ảnh hưởng mạnh hơn**_ _:_\n\n\n_x_ _j_ _·_ _q_\n_K_ cos ( _x_ _j_ _, q_ ) = cos( _x_ _j_ _, q_ ) = (21)\n_∥x_ _j_ _∥× ∥q∥_\n\n\n**Mệnh đề2** (Tính chất Kernel) **.** _K_ cos _là một Mercer kernel hợp lệthỏa mãn dựa trên nghiên cứu Ghojogh,_\n_B., Ghodsi, A., Karray, F., & Crowl..."
|
| 515 |
+
}
|
| 516 |
+
],
|
| 517 |
+
"model_verdict": null
|
| 518 |
+
},
|
| 519 |
+
"15": {
|
| 520 |
+
"supported_by_embeddings": true,
|
| 521 |
+
"max_similarity": 0.9300246834754944,
|
| 522 |
+
"evidence": [
|
| 523 |
+
{
|
| 524 |
+
"idx": 3,
|
| 525 |
+
"page": 28,
|
| 526 |
+
"score": 0.746843695640564,
|
| 527 |
+
"text": "**–**\nNhờđó, mô hình có thểhiểu được sựkhác biệt tinh tếgiữa các cách diễn đạt, xửlý được\ncác từđồng nghĩa và các biến thểngôn ngữ. **Nhược điểm:**\n\n\n**– Đòi hỏi tài nguyên tính toán lớn:** Việc huấn luyện và fine-tuning các mô hình này cần\nnhiều thời gian và chi phí. **– Phức tạp:** Việc fine-tuning cho từng tác vụcụthểcó thểphức tạp. Đặc biệt, nếu không có\nđủdữliệu đã được gán nhãn, hiệu quảcủa các mô hình này sẽbịhạn chế. **7.3** **Phương pháp Semi-supervised sub-category của spam**\n\n\nĐểtận dụng ưu điểm của 2 phương pháp phân loại sub-category phần trên. Chúng tôi đềxuất thực\nhiện một phương pháp semi-supervised bằng cách kết hợp bert embeđings với nối từkhóa. Phương pháp này được gọi là ”bán giám sát” vì nó sửdụng một lượng nhỏdữliệu có nhãn (reference_texts\nvà category_keywords) đểphân loại một lượng lớn dữliệu chưa có nhãn (spam_texts). Tiến trình thực hiện của phương pháp như sau:\n\n\n1. **Bước 1: BERT embeddings**\n\n\n **Tạo Embeddings của Văn bản Spam:** đểbiến mỗi tin nhắn spam ..."
|
| 528 |
+
},
|
| 529 |
+
{
|
| 530 |
+
"idx": 2,
|
| 531 |
+
"page": 15,
|
| 532 |
+
"score": 0.8782092928886414,
|
| 533 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n\nmua, thanh toán,.... **Bi-directional (hai chiều):** Ngữnghĩa của một từkhông chỉđược biểu diễn bởi những từliền trước\nmà còn được giải thích bởi toàn bộcác từxung quanh. Luồng giải thích tuân theo đồng thời từtrái\nqua phải và từphải qua trái cùng một lúc. Đại diện cho các phép biểu diễn từnày là những mô hình\nsửdụng kỹthuật transformer ví dụnhư BERT. **5.2** **BERT là gì?**\n\n\nBERT (Bidirectional Encoder Representations from Transformers) là một mô hình học sâu tiên tiến do\nGoogle phát triển, nổi bật với khảnăng hiểu ngữcảnh ngôn ngữtựnhiên theo hai chiều. Trong bài toán\nphân loại tin nhắn spam/ham, BERT chuyển đổi tin nhắn thành biểu diễn số, nắm bắt ngữcảnh sâu sắc,\nvà dựđoán nhãn (spam hoặc ham) với độchính xác cao. Kiến trúc BERT-base gồm **12 lớp encoder**\n**Transformer**, mỗi lớp có **768 chiều ẩn** (hidden size) và **12 head attention**, với tổng cộng khoảng\n**110 triệu tham số** . Mô hình được huấn luyện trước trên dữliệu lớn (Wikipedia, Bo..."
|
| 534 |
+
},
|
| 535 |
+
{
|
| 536 |
+
"idx": 16,
|
| 537 |
+
"page": 13,
|
| 538 |
+
"score": 0.9300246834754944,
|
| 539 |
+
"text": "Nếu có thêm thời gian, nhóm sẽmởrộng phương pháp này đểgiải thích cho cảcác câu được\nphân loại là ham, tuy nhiên cách làm sẽhoàn toàn tương tự. **Ý tưởng thuật toán:** Đầu tiên, ta tính `spam_scores` ban đầu — là tổng điểm tương đồng giữa\nembedding của câu đầu vào với các láng giềng có nhãn “spam” trong tập huấn luyện. Sau đó, ta đo\nmức độgiảm điểm `spam_scores` khi lần lượt che từng token, theo các bước sau:\n\n\n13"
|
| 540 |
+
}
|
| 541 |
+
],
|
| 542 |
+
"model_verdict": null
|
| 543 |
+
},
|
| 544 |
+
"16": {
|
| 545 |
+
"supported_by_embeddings": true,
|
| 546 |
+
"max_similarity": 1.2162450551986694,
|
| 547 |
+
"evidence": [
|
| 548 |
+
{
|
| 549 |
+
"idx": 46,
|
| 550 |
+
"page": 11,
|
| 551 |
+
"score": 0.9961504340171814,
|
| 552 |
+
"text": "**Xây dựng tập cụm ngữnghĩa theo chủđề** : Các nhóm cụm từđược phân loại theo 7 chủđề\ndễgây nhầm lẫn giữa spam và ham, bao gồm:\n\n\n - `financial_phrases` (liên quan đến giao dịch, tiền bạc)\n\n\n - `promotion_phrases` (quảng cáo, ưu đãi)\n\n - `lottery_phrases` (trúng thưởng, phần thưởng)\n\n\n - `scam_alert_phrases` (cảnh báo giảmạo)\n\n\n - `call_to_action_phrases` (dẫn dụngười dùng hành động)\n\n\n - `social_engineering_phrases` (lừa đảo cảm xúc)\n\n - `obfuscated_phrases` (che giấu, tránh bộlọc spam)\n\n\n2. **Sinh dữliệu bằng kịch bản và LLM** :\n\n\n - Với mỗi nhóm cụm từ, nhóm thiết kếmột tập các kịch bản “base” như: _“Hey, did you hear_\n_about...”_, _“Bro, you should check this out”_ ... - Các cụm spam hoặc ham tương ứng được **chèn vào base**, tạo ra các mẫu dữliệu mới, theo\ncấu trúc _“base + insert”_ hoặc _“insert + base”_ . - Ngoài ra, nhóm chúng mình sửdụng LLM (như GPT hoặc Mixtral) đểsinh các câu mới theo\ntemplate kịch bản thực tế, nhằm tái hiện các loại spam ngụy trang phổbiến."
|
| 553 |
+
},
|
| 554 |
+
{
|
| 555 |
+
"idx": 66,
|
| 556 |
+
"page": 3,
|
| 557 |
+
"score": 1.1186320781707764,
|
| 558 |
+
"text": "**Email Spam là gì?**\n\n\n\n\n\n**Ví dụ(Spam Email):**\n\n\n _“Win a brand new iPhone today! Just click this link to claim!”_\n\n\n _“You’ve been selected for a $1000 Walmart gift card!”_\n\n\n _“Invest in crypto now and double your money overnight!”_\n\n\n**Email Ham là gì?**\n\n\n\n\n\n**Ví dụ(Ham Email):**\n\n\n _“Hi John, just a reminder that your doctor’s appointment is at 3PM today.”_\n\n\n _“Your monthly salary has been transferred to your account.”_\n\n\n _“Please review the attached report before the meeting tomorrow.”_\n\n\n3"
|
| 559 |
+
},
|
| 560 |
+
{
|
| 561 |
+
"idx": 26,
|
| 562 |
+
"page": 14,
|
| 563 |
+
"score": 1.2162450551986694,
|
| 564 |
+
"text": "Các kết quảbiểu diễn từđã\ncó bối cảnh nhưng chỉđược giải thích bởi một chiều từtrái qua phải hoặc từphải qua trái. VD:\n\n\n**Câu C:** Hôm nay tôi mang 200 tỷ[gửi] ởngân hàng. **Câu D:** Hôm nay tôi mang 200 tỷ[gửi] …. Như vậy véc tơ biểu diễn của từ **gửi** được xác định thông qua các từliền trước với nó. Nếu chỉdựa vào\ncác từliền trước Hôm nay tôi mang 200 tỷthì ta có thểnghĩ từphù hợp ởvịtrí hiện tại là cho vay,\n\n\n14"
|
| 565 |
+
}
|
| 566 |
+
],
|
| 567 |
+
"model_verdict": null
|
| 568 |
+
},
|
| 569 |
+
"17": {
|
| 570 |
+
"supported_by_embeddings": true,
|
| 571 |
+
"max_similarity": 0.6036962270736694,
|
| 572 |
+
"evidence": [
|
| 573 |
+
{
|
| 574 |
+
"idx": 21,
|
| 575 |
+
"page": 15,
|
| 576 |
+
"score": 0.5917988419532776,
|
| 577 |
+
"text": "Trong bài toán spam/ham, BERT được tinh\nchỉnh đểtối ưu hóa dựđoán nhãn và tập trung vào các từkhóa quan trọng như “miễn phí” hoặc “quà\ntặng” trong tin nhắn spam. **Ứng dụng** : Trong phân loại tin nhắn spam/ham, BERT chuyển tin nhắn thành vector số, hiểu ngữ\ncảnh sâu sắc (ví dụ: nhận diện ”miễn phí” trong ngữcảnh quảng cáo), và dựđoán nhãn (spam hoặc\nham). **Ưu điểm** :\n\n\n - Hiểu ngữcảnh hai chiều, vượt trội so với các phương pháp truyền thống như TF-IDF. - Sửdụng vector [CLS] đểtổng hợp thông tin toàn câu, phù hợp cho phân loại. **5.3** **Kiến trúc BERT**\n\n\nQuy trình xửlý của BERT bao gồm ba giai đoạn chính:\n\n\n1. **Mã hóa đầu vào** : Chuyển tin nhắn thành token, embedding, và attention mask. 2. **Xửlý qua Transformer encoder** : Tạo biểu diễn ngữcảnh cho từng token, đặc biệt là vector\n\n[CLS]. 3. **Phân loại** : Sửdụng vector [CLS] đểdựđoán nhãn spam/ham. Phần này trình bày chi tiết từng thành phần của kiến trúc BERT và cách chúng hỗtrợbài toán phân\nloại tin nhắn spam/ham. **5.3.1** *..."
|
| 578 |
+
},
|
| 579 |
+
{
|
| 580 |
+
"idx": 1,
|
| 581 |
+
"page": 5,
|
| 582 |
+
"score": 0.6036962270736694,
|
| 583 |
+
"text": "Điều này đặc biệt quan trọng\ntrong các hệthống chống spam hiện đại, giúp người dùng hiểu rõ liệu một email nên bịxóa, xem qua\nhay báo cáo. Ngoài ra, nhóm còn hướng đến việc **mởrộng phân loại chi tiết trong nhóm spam**\n(quảng cáo, hệthống, lừa đảo, v.v...) nhằm tăng trải nghiệm và bảo mật cho người dùng. Hệthống phân loại tin nhắn spam/ham được thiết kếvới cơ chếđầu vào – đầu ra như sau:\n\n\n\n\n\n5"
|
| 584 |
+
}
|
| 585 |
+
],
|
| 586 |
+
"model_verdict": null
|
| 587 |
+
},
|
| 588 |
+
"18": {
|
| 589 |
+
"supported_by_embeddings": true,
|
| 590 |
+
"max_similarity": 0.974981427192688,
|
| 591 |
+
"evidence": [
|
| 592 |
+
{
|
| 593 |
+
"idx": 3,
|
| 594 |
+
"page": 28,
|
| 595 |
+
"score": 0.5795202255249023,
|
| 596 |
+
"text": "**–**\nNhờđó, mô hình có thểhiểu được sựkhác biệt tinh tếgiữa các cách diễn đạt, xửlý được\ncác từđồng nghĩa và các biến thểngôn ngữ. **Nhược điểm:**\n\n\n**– Đòi hỏi tài nguyên tính toán lớn:** Việc huấn luyện và fine-tuning các mô hình này cần\nnhiều thời gian và chi phí. **– Phức tạp:** Việc fine-tuning cho từng tác vụcụthểcó thểphức tạp. Đặc biệt, nếu không có\nđủdữliệu đã được gán nhãn, hiệu quảcủa các mô hình này sẽbịhạn chế. **7.3** **Phương pháp Semi-supervised sub-category của spam**\n\n\nĐểtận dụng ưu điểm của 2 phương pháp phân loại sub-category phần trên. Chúng tôi đềxuất thực\nhiện một phương pháp semi-supervised bằng cách kết hợp bert embeđings với nối từkhóa. Phương pháp này được gọi là ”bán giám sát” vì nó sửdụng một lượng nhỏdữliệu có nhãn (reference_texts\nvà category_keywords) đểphân loại một lượng lớn dữliệu chưa có nhãn (spam_texts). Tiến trình thực hiện của phương pháp như sau:\n\n\n1. **Bước 1: BERT embeddings**\n\n\n **Tạo Embeddings của Văn bản Spam:** đểbiến mỗi tin nhắn spam ..."
|
| 597 |
+
},
|
| 598 |
+
{
|
| 599 |
+
"idx": 61,
|
| 600 |
+
"page": 26,
|
| 601 |
+
"score": 0.8431670665740967,
|
| 602 |
+
"text": "Những cải thiện này đến từcác yếu tốsau:\n\n\n **Tăng cường dữliệu:** sinh thêm mẫu khó và thay từđồng nghĩa giúp đa dạng hóa ngữcảnh và\nlàm mô hình học được ranh giới phân biệt tốt hơn. **Tập huấn luyện lớn hơn:** từdưới 1.000 mẫu lên hơn 9.000 mẫu giúp mô hình tổng quát hóa\ntốt hơn. **Tập trung vào mẫu khó:** ưu tiên những ví dụgần ranh giới giữa spam/ham nhằm tăng tính\nphân biệt cho mô hình. **Kết luận:** Mô hình mới không chỉđạt hiệu suất cao ở _k_ = 5 mà còn cải thiện đáng kểở _k_ = 1, rất hữu\ních cho các ứng dụng yêu cầu tốc độsuy luận nhanh mà vẫn đảm bảo độchính xác cao. 26"
|
| 603 |
+
},
|
| 604 |
+
{
|
| 605 |
+
"idx": 13,
|
| 606 |
+
"page": 14,
|
| 607 |
+
"score": 0.974981427192688,
|
| 608 |
+
"text": "Hiệu quảbiểu thịnội dung và truyền đạt ý nghĩa sẽlớn hơn so với từng từđứng độc lập. Ngữcảnh trong câu có một sựảnh hưởng rất lớn trong việc giải thích ý nghĩa của từ. Hiểu được vai\ntrò mấu chốt đó, các thuật toán NLP SOTA đều cốgắng đưa ngữcảnh vào mô hình nhằm tạo ra sự\nđột phá, giúp mô hình học được thông tin chính xác hơn. Phân cấp mức độphát triển của các phương pháp embedding từtrong NLP có thểbao gồm các nhóm:\n\n\n**Non-context (không bối cảnh):** Là các thuật toán không tồn tại bối cảnh trong biểu diễn từ. Đó là\ncác thuật toán NLP đời đầu như ‘ word2vec, GLoVe, fasttext‘. Chúng ta chỉcó duy nhất một biểu diễn\nvéc tơ cho mỗi một từmà không thay đổi theo bối cảnh. VD:\n\n\n**Câu A:** Cánh [đồng] này sắp được thu hoạch. **Câu B:** Tôi [đồng] ý với ý kiến của anh! Thì từ **đồng** sẽmang 2 ý nghĩa khác nhau nên phải có hai biểu diễn từriêng biệt. Các thuật toán\nnon-context không đáp ứng được sựđa dạng vềngữnghĩa của từtrong NLP. **Uni-directional (một chiều):** Là các thuật toán đã bắt đ..."
|
| 609 |
+
}
|
| 610 |
+
],
|
| 611 |
+
"model_verdict": null
|
| 612 |
+
},
|
| 613 |
+
"19": {
|
| 614 |
+
"supported_by_embeddings": true,
|
| 615 |
+
"max_similarity": 0.7636357545852661,
|
| 616 |
+
"evidence": [
|
| 617 |
+
{
|
| 618 |
+
"idx": 14,
|
| 619 |
+
"page": 20,
|
| 620 |
+
"score": 0.6900026798248291,
|
| 621 |
+
"text": "**6.1** **Khung Phân loại Trọng sốĐềxuất**\n\n\nVì vậy nhóm đã nghiên cứu và đềxuất áp dụng công thức trọng sốmới trong quá trình voting của KNN\nbằng kết hợp hai yếu tốtương đồng (similarity) và t���m quan trọng tinh tếcủa từng thực thể(saliency). **6.2** **Công thức Cốt lõi**\n\n\nweight( _x_ _j_ _,_ _q_ ) = (1 _−_ _α_ ) _×_ similarity( _x_ _j_ _,_ _q_ ) _×_ ICF( _y_ ( _x_ _j_ )) + _α ×_ saliency( _x_ _j_ _,_ _q_ ) (5)\n\n\nTrong đó:\n\n\n_x_ _j_ _·_ _q_\nsimilarity( _x_ _j_ _, q_ ) = cos( _x_ _j_ _, q_ ) = (6)\n_∥x_ _j_ _∥× ∥q∥_\n\n\n\n_N_\nICF( _c_ _i_ ) =\n_M × n_ _i_\n\n\n\n(7)\n\n\n\nsaliency( _x_ _j_ _, q_ ) = _∥∇_ _x_ _j_ _L_ ( _f_ ( _x_ _j_ ) _,_ ˆ _y_ ) _∥_ 2 (8)\n\n_α ∈_ [0 _,_ 1] (tham sốcân bằng) (9)\n\n\n**6.3** **Quyết định Phân loại Cuối cùng**\n\n\n\nˆ\n_y_ = arg max\n_c_ _i_ _∈C_\n\n\n\n�\n\n_x_ _j_ _∈N_ _K_ ( _q_ )\n_y_ ( _x_ _j_ )= _c_ _i_\n\n\n20\n\n\n\nweight( _x_ _j_ _, q_ ) (10)"
|
| 622 |
+
},
|
| 623 |
+
{
|
| 624 |
+
"idx": 0,
|
| 625 |
+
"page": 19,
|
| 626 |
+
"score": 0.7097625732421875,
|
| 627 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n## **6 KNN with Weight Voting**\n\n\n**1.6.1 Vấn đềMất cân bằng Lớp trong K-Nearest Neighbors**\n\n\nPhân phối lớp mất cân bằng đại diện cho cảthách thức lý thuyết và thực tiễn trong phân loại KNearest Neighbors, được tài liệu hóa rộng rãi trong văn hệmáy học (A survey on imbalanced learning:\nlatest research, applications and future directions: https://link.springer.com/article/10.1007/s10462024-10759-6). Vấn đềnày trởnên đặc biệt nghiêm trọng trong các lĩnh vực có phân phối lớp bịlệch tự\nnhiên, chẳng hạn như phát hiện gian lận (giao dịch gian lận _∼_ 0 _._ 1%), sàng lọc y tế(tỷlệmắc bệnh\n_∼_ 1 _−_ 5%), và lọc thư rác (tỷlệspam _∼_ 10 _−_ 40%). Vấn đềcơ bản xuất phát từviệc KNN dựa vào **majority voting**, hệthống ưu tiên lớp chiếm ưu thế\nbất kểmức độliên quan ngữnghĩa của từng láng giềng. Hình 2: Enter Caption\n\n\n**1.7.1 Hạn chếcủa Majority Voting trong Môi trường Mất cân bằng**\n\n\n**1.7.1.1 Phân tích Toán học vềBias của Majority Voting**\n\n\nGọi _C_ = _{c_ ..."
|
| 628 |
+
},
|
| 629 |
+
{
|
| 630 |
+
"idx": 33,
|
| 631 |
+
"page": 6,
|
| 632 |
+
"score": 0.7636357545852661,
|
| 633 |
+
"text": "**Similarity Search (KNN-Classifier):**\n\n\n **Vấn đềtồn đọng:** Phương pháp bỏphiếu đa số( _majority vote_ ) đơn giản trong KNN bỏqua\nmức độquan trọng của từng hàng xóm, nên các điểm ”xa” nhưng đông vẫn có thểáp đảo những\nđiểm ”gần” và ảnh hưởng sai lệch đến kết quảphân loại. **Giải pháp:** Khi có một tin nhắn mới, hệthống tìm kiếm những tin nhắn tương tựnhất. Quyết\nđịnh phân loại được đưa ra bằng Weighted KNN, sửdụng độtương đồng ( _similarity score_ ) làm\ntrọng sốđểưu tiên các hàng xóm gần hơn. 6"
|
| 634 |
+
}
|
| 635 |
+
],
|
| 636 |
+
"model_verdict": null
|
| 637 |
+
},
|
| 638 |
+
"20": {
|
| 639 |
+
"supported_by_embeddings": true,
|
| 640 |
+
"max_similarity": 1.0194404125213623,
|
| 641 |
+
"evidence": [
|
| 642 |
+
{
|
| 643 |
+
"idx": 41,
|
| 644 |
+
"page": 19,
|
| 645 |
+
"score": 0.8875085115432739,
|
| 646 |
+
"text": "Đối với điểm truy vấn _q_, KNN truyền thống tính toán:\n\n\nˆ\n_y_ = arg max _c_ _i_ _∈C_ _[|{][x]_ _[j]_ _[ ∈N]_ _[K]_ [(] _[q]_ [) :] _[ y]_ [(] _[x]_ _[j]_ [) =] _[ c]_ _[i]_ _[}|]_ (1)\n\n\n**Phân tích Bias:**\nXác suất đểmột K-neighborhood ngẫu nhiên chứa _k_ thực thểtừlớp _c_ _i_ tuân theo phân phối siêu hình\nhọc:\n\n\n19"
|
| 647 |
+
},
|
| 648 |
+
{
|
| 649 |
+
"idx": 28,
|
| 650 |
+
"page": 16,
|
| 651 |
+
"score": 1.0129456520080566,
|
| 652 |
+
"text": "**Position Embedding** : Biểu diễn vịtrí của token (0, 1, 2, ...) đểgiữthông tin thứtự(Trong\nBERT, Position Embedding không sửdụng hàm sin/cosin như Transformer gốc, mà là các\nvector học được (learned embeddings)). **Segment Embedding** : Phân biệt các câu (thường là 0 cho một tin nhắn). Ví dụ: Token “miễn” ởvịtrí 5:\n\n\n - Token Embedding: `[0.2, 0.1, ..., 0.3]` (768 chiều). - Position Embedding: `[0.01, -0.02, ..., 0.1]` (vịtrí 5). - Segment Embedding: `[0, 0, ..., 0]` (một câu). - Tổng embedding: `[0.21, 0.08, ..., 0.4]` (768 chiều). Kết quả: Ma trận embedding **16** _×_ **768** (16 token _×_ 768 chiều). 4. **Attention Mask** : Vector nhịphân chỉđịnh token nào được xửlý (1 cho token thực, 0 cho [PAD]). Ví dụ: `[1, 1, 1, 1, 1, 1, 1, 1, 1, 0, ..., 0]` (9 token thực, 7 [PAD]). **Liên hệvới spam/ham** Mã hóa đầu vào đảm bảo tin nhắn như “Nhận ngay quà tặng miễn phí!”\nđược chuyển thành ma trận số, với token [CLS] đóng vai trò tổng hợp ngữcảnh (như đặc trưng quảng\ncáo của “miễn phí”) đểhỗ..."
|
| 653 |
+
},
|
| 654 |
+
{
|
| 655 |
+
"idx": 18,
|
| 656 |
+
"page": 7,
|
| 657 |
+
"score": 1.0194404125213623,
|
| 658 |
+
"text": "Tham số _α_ là tham sốđiều chỉnh, quyết định mức độưu tiên của điểm saliency so với độ\ntương đồng tổng thểcủa tin nhắn. - **Vote Scores:** Hệthống hiển thịđiểm sốbỏphiếu cho mỗi lớp ( _Ham_ và _Spam_ ). Dựđoán cuối\ncùng sẽlà lớp có điểm sốcao nhất. - **Spam Subcategory:** Nếu tin nhắn được phân loại là _SPAM_, hệthống tiếp tục phân tích đểxác\nđịnh tiểu mục spam cụthể(ví dụ: _spam_quangcao_, _spam_hethong_ ). **Cơ sởgiải thích (Top neighbors):** Hệthống liệt kê một sốhàng xóm gần nhất trong cơ sởdữ\nliệu vector. Mỗi neighbors bao gồm:\n\n\n**–** _Nhãn (Label):_ Nhãn của tin nhắn gốc ( _ham_ hoặc _spam_ ). **–**\n_Độtương đồng (Similarity):_ Giá trịthểhiện mức độtương đồng giữa tin nhắn đầu vào và\nhàng xóm. **–**\n_Nội dung (Message):_ Nội dung của tin nhắn hàng xóm. 7"
|
| 659 |
+
}
|
| 660 |
+
],
|
| 661 |
+
"model_verdict": null
|
| 662 |
+
}
|
| 663 |
+
}
|
| 664 |
+
}
|
test/mcq_output.json
CHANGED
|
@@ -1,162 +1,199 @@
|
|
| 1 |
{
|
| 2 |
"mcqs": {
|
| 3 |
"1": {
|
| 4 |
-
"câu hỏi": "Trong
|
| 5 |
"lựa chọn": {
|
| 6 |
-
"a": "
|
| 7 |
-
"b": "
|
| 8 |
-
"c": "
|
| 9 |
-
"d": "
|
| 10 |
},
|
| 11 |
-
"đáp án": "
|
| 12 |
},
|
| 13 |
"2": {
|
| 14 |
-
"câu hỏi": "
|
| 15 |
"lựa chọn": {
|
| 16 |
-
"a": "
|
| 17 |
-
"b": "
|
| 18 |
-
"c": "
|
| 19 |
-
"d": "
|
| 20 |
},
|
| 21 |
-
"đáp án": "
|
| 22 |
},
|
| 23 |
"3": {
|
| 24 |
-
"câu hỏi": "
|
| 25 |
"lựa chọn": {
|
| 26 |
-
"a": "
|
| 27 |
-
"b": "
|
| 28 |
-
"c": "
|
| 29 |
-
"d": "
|
| 30 |
},
|
| 31 |
-
"đáp án": "
|
| 32 |
},
|
| 33 |
"4": {
|
| 34 |
-
"câu hỏi": "
|
| 35 |
"lựa chọn": {
|
| 36 |
-
"a": "
|
| 37 |
-
"b": "
|
| 38 |
-
"c": "
|
| 39 |
-
"d": "
|
| 40 |
},
|
| 41 |
-
"đáp án": "
|
| 42 |
},
|
| 43 |
"5": {
|
| 44 |
-
"câu hỏi": "Theo
|
| 45 |
"lựa chọn": {
|
| 46 |
-
"a": "
|
| 47 |
-
"b": "
|
| 48 |
-
"c": "
|
| 49 |
-
"d": "
|
| 50 |
},
|
| 51 |
-
"đáp án": "
|
| 52 |
}
|
| 53 |
},
|
| 54 |
"validation": {
|
| 55 |
"1": {
|
| 56 |
"supported_by_embeddings": true,
|
| 57 |
-
"max_similarity":
|
| 58 |
"evidence": [
|
| 59 |
{
|
| 60 |
-
"idx":
|
| 61 |
-
"page":
|
| 62 |
-
"score": 0.
|
| 63 |
-
"text": "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
}
|
| 65 |
],
|
| 66 |
"model_verdict": {
|
| 67 |
-
"supported":
|
| 68 |
-
"confidence": 0.
|
| 69 |
-
"evidence": "",
|
| 70 |
-
"reason": "Context
|
| 71 |
}
|
| 72 |
},
|
| 73 |
"2": {
|
| 74 |
"supported_by_embeddings": true,
|
| 75 |
-
"max_similarity":
|
| 76 |
"evidence": [
|
| 77 |
{
|
| 78 |
-
"idx":
|
| 79 |
-
"page":
|
| 80 |
-
"score": 0.
|
| 81 |
-
"text": "**
|
| 82 |
},
|
| 83 |
{
|
| 84 |
-
"idx":
|
| 85 |
-
"page":
|
| 86 |
-
"score": 0.
|
| 87 |
-
"text": "
|
| 88 |
},
|
| 89 |
{
|
| 90 |
-
"idx":
|
| 91 |
-
"page":
|
| 92 |
-
"score":
|
| 93 |
-
"text": "
|
| 94 |
}
|
| 95 |
],
|
| 96 |
"model_verdict": {
|
| 97 |
"supported": true,
|
| 98 |
"confidence": 0.99,
|
| 99 |
-
"evidence": "
|
| 100 |
-
"reason": "Context explicitly states
|
| 101 |
}
|
| 102 |
},
|
| 103 |
"3": {
|
| 104 |
"supported_by_embeddings": true,
|
| 105 |
-
"max_similarity": 0.
|
| 106 |
"evidence": [
|
| 107 |
{
|
| 108 |
-
"idx":
|
| 109 |
-
"page":
|
| 110 |
-
"score": 0.
|
| 111 |
-
"text": "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 112 |
},
|
| 113 |
{
|
| 114 |
-
"idx":
|
| 115 |
-
"page":
|
| 116 |
-
"score": 0.
|
| 117 |
-
"text": "
|
| 118 |
}
|
| 119 |
],
|
| 120 |
"model_verdict": {
|
| 121 |
"supported": true,
|
| 122 |
-
"confidence":
|
| 123 |
-
"evidence": "
|
| 124 |
-
"reason": "
|
| 125 |
}
|
| 126 |
},
|
| 127 |
"4": {
|
| 128 |
-
"supported_by_embeddings":
|
| 129 |
-
"max_similarity": 0.
|
| 130 |
-
"evidence": [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 131 |
"model_verdict": {
|
| 132 |
-
"supported":
|
| 133 |
-
"confidence": 0.
|
| 134 |
-
"evidence": "",
|
| 135 |
-
"reason": "
|
| 136 |
}
|
| 137 |
},
|
| 138 |
"5": {
|
| 139 |
"supported_by_embeddings": true,
|
| 140 |
-
"max_similarity":
|
| 141 |
"evidence": [
|
| 142 |
{
|
| 143 |
-
"idx":
|
| 144 |
-
"page":
|
| 145 |
-
"score": 0.
|
| 146 |
-
"text": "**AI VIETNAM
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 147 |
},
|
| 148 |
{
|
| 149 |
-
"idx":
|
| 150 |
-
"page":
|
| 151 |
-
"score":
|
| 152 |
-
"text": "
|
| 153 |
}
|
| 154 |
],
|
| 155 |
"model_verdict": {
|
| 156 |
"supported": true,
|
| 157 |
"confidence": 0.99,
|
| 158 |
-
"evidence": "
|
| 159 |
-
"reason": "Context
|
| 160 |
}
|
| 161 |
}
|
| 162 |
}
|
|
|
|
| 1 |
{
|
| 2 |
"mcqs": {
|
| 3 |
"1": {
|
| 4 |
+
"câu hỏi": "Trong bảng tổng hợp các nhóm nội dung dễ gây nhầm lẫn, nhóm nào liên quan đến giao dịch tiền bạc?",
|
| 5 |
"lựa chọn": {
|
| 6 |
+
"a": "promotion_phrases",
|
| 7 |
+
"b": "financial_phrases",
|
| 8 |
+
"c": "lottery_phrases",
|
| 9 |
+
"d": "scam_alert_phrases"
|
| 10 |
},
|
| 11 |
+
"đáp án": "financial_phrases"
|
| 12 |
},
|
| 13 |
"2": {
|
| 14 |
+
"câu hỏi": "Theo mô tả về kiến trúc BERT‑base trong nội dung, mô hình này có bao nhiêu lớp encoder Transformer?",
|
| 15 |
"lựa chọn": {
|
| 16 |
+
"a": "10",
|
| 17 |
+
"b": "12",
|
| 18 |
+
"c": "24",
|
| 19 |
+
"d": "48"
|
| 20 |
},
|
| 21 |
+
"đáp án": "12"
|
| 22 |
},
|
| 23 |
"3": {
|
| 24 |
+
"câu hỏi": "Theo Định lý 6.1 (Tính chất Convex Combination), công thức tính trọng số kết hợp bằng tham số α là gì?",
|
| 25 |
"lựa chọn": {
|
| 26 |
+
"a": "weight = (1 - α) × w_similarity × ICF + α × w_saliency",
|
| 27 |
+
"b": "weight = α × w_similarity × ICF + (1 - α) × w_saliency",
|
| 28 |
+
"c": "weight = w_similarity + w_saliency",
|
| 29 |
+
"d": "weight = α × (w_similarity + w_saliency)"
|
| 30 |
},
|
| 31 |
+
"đáp án": "weight = (1 - α) × w_similarity × ICF + α × w_saliency"
|
| 32 |
},
|
| 33 |
"4": {
|
| 34 |
+
"câu hỏi": "Theo nội dung, một nhược điểm của phương pháp dựa trên từ khóa trong việc phát hiện spam là gì?",
|
| 35 |
"lựa chọn": {
|
| 36 |
+
"a": "Có thể xử lý các biến thể và lỗi chính tả",
|
| 37 |
+
"b": "Thiếu linh hoạt khi từ khóa thay đổi",
|
| 38 |
+
"c": "Không hiểu ngữ cảnh của từ trong các câu",
|
| 39 |
+
"d": "Đòi hỏi tính toán phức tạp"
|
| 40 |
},
|
| 41 |
+
"đáp án": "Không hiểu ngữ cảnh của từ trong các câu"
|
| 42 |
},
|
| 43 |
"5": {
|
| 44 |
+
"câu hỏi": "Theo đoạn văn, điều nào sau đây mô tả đúng về mô hình BERT?",
|
| 45 |
"lựa chọn": {
|
| 46 |
+
"a": "BERT có 12 lớp encoder, mỗi lớp có kích thước ẩn là 768 và 12 attention head.",
|
| 47 |
+
"b": "BERT chỉ được huấn luyện bằng nhiệm vụ Dự đoán câu tiếp theo (Next Sentence Prediction - NSP).",
|
| 48 |
+
"c": "BERT sử dụng kiến trúc một chiều, chỉ xử lý văn bản từ trái sang phải.",
|
| 49 |
+
"d": "BERT bao gồm 24 lớp encoder và kích thước ẩn là 1024."
|
| 50 |
},
|
| 51 |
+
"đáp án": "BERT có 12 lớp encoder, mỗi lớp có kích thước ẩn là 768 và 12 attention head."
|
| 52 |
}
|
| 53 |
},
|
| 54 |
"validation": {
|
| 55 |
"1": {
|
| 56 |
"supported_by_embeddings": true,
|
| 57 |
+
"max_similarity": 1.0912104845046997,
|
| 58 |
"evidence": [
|
| 59 |
{
|
| 60 |
+
"idx": 27,
|
| 61 |
+
"page": 4,
|
| 62 |
+
"score": 0.7866219282150269,
|
| 63 |
+
"text": "Dưới đây là bảng tổng hợp các nhóm nội dung dễgây nhầm lẫn – xuất hiện trong cảham và spam tinh\nvi, đòi hỏi mô hình phải rất tinh tếmới phân biệt được:\n\n\n\n|Nhóm nội dung|Ví dụ nội dung|Dễ nhầm với|\n|---|---|---|\n|`financial_phrases`|“Please<br>confrm<br>the<br>$200<br>transfer<br>from<br>your<br>account.”<br>“Your invoice for June is now available.”|Scam / Phishing|\n|`promotion_phrases`|“Flash sale ends tonight – 30% of all items!”<br>“Exclusive discount for HUST students.”|Spam quảng cáo|\n|`lottery_phrases`|“You’ve been selected for a loyalty reward.”<br>“You may be eligible for a lucky draw.”|Spam quà tặng /<br>Random Reward|\n|`scam_alert_phrases`|“Unusual login detected. Was this you?”<br>“A payment attempt was blocked on your card.”|Cảnh báo giả/ Giả<br>danh ngân hàng|\n|`call_to_action_phrases`|“Act now to secure your spot in the seminar.”<br>“Verify your email to complete registration.”|Spam ép buộc /<br>Confrmation bait|\n\n\n4"
|
| 64 |
+
},
|
| 65 |
+
{
|
| 66 |
+
"idx": 46,
|
| 67 |
+
"page": 11,
|
| 68 |
+
"score": 0.7944862842559814,
|
| 69 |
+
"text": "**Xây dựng tập cụm ngữnghĩa theo chủđề** : Các nhóm cụm từđược phân loại theo 7 chủđề\ndễgây nhầm lẫn giữa spam và ham, bao gồm:\n\n\n - `financial_phrases` (liên quan đến giao dịch, tiền bạc)\n\n\n - `promotion_phrases` (quảng cáo, ưu đãi)\n\n - `lottery_phrases` (trúng thưởng, phần thưởng)\n\n\n - `scam_alert_phrases` (cảnh báo giảmạo)\n\n\n - `call_to_action_phrases` (dẫn dụngười dùng hành động)\n\n\n - `social_engineering_phrases` (lừa đảo cảm xúc)\n\n - `obfuscated_phrases` (che giấu, tránh bộlọc spam)\n\n\n2. **Sinh dữliệu bằng kịch bản và LLM** :\n\n\n - Với mỗi nhóm cụm từ, nhóm thiết kếmột tập các kịch bản “base” như: _“Hey, did you hear_\n_about...”_, _“Bro, you should check this out”_ ... - Các cụm spam hoặc ham tương ứng được **chèn vào base**, tạo ra các mẫu dữliệu mới, theo\ncấu trúc _“base + insert”_ hoặc _“insert + base”_ . - Ngoài ra, nhóm chúng mình sửdụng LLM (như GPT hoặc Mixtral) đểsinh các câu mới theo\ntemplate kịch bản thực tế, nhằm tái hiện các loại spam ngụy trang phổbiến."
|
| 70 |
+
},
|
| 71 |
+
{
|
| 72 |
+
"idx": 44,
|
| 73 |
+
"page": 12,
|
| 74 |
+
"score": 1.0912104845046997,
|
| 75 |
+
"text": "Tuy nhiên sau khi chèn cụm “$200 cashback”, nó trởthành\nmột tin nhắn spam ngụy trang. Những câu như vậy rất khó nhận diện nếu chỉhuấn luyện từtập dữ\nliệu spam kiểu cũ. **Tác dụng**\n\n\nViệc áp dụng data augmentation theo hướng có kiểm soát giúp:\n\n\n **Giảm hiện tượng bias** của mô hình khi gặp spam đời thực, vốn thường mang ngôn ngữtựnhiên\nvà ẩn dụhơn là spam thô sơ kiểu “FREE!!! Click now!!!”\n\n\n **Tăng độrobust** của hệthống khi xửlý các tin nhắn có bềngoài giống ham nhưng nội dung\ntiềm ẩn spam. 12"
|
| 76 |
}
|
| 77 |
],
|
| 78 |
"model_verdict": {
|
| 79 |
+
"supported": true,
|
| 80 |
+
"confidence": 0.99,
|
| 81 |
+
"evidence": "`financial_phrases` (liên quan đến giao dịch, tiền bạc)",
|
| 82 |
+
"reason": "Context explicitly states that the group 'financial_phrases' is related to transactions and money."
|
| 83 |
}
|
| 84 |
},
|
| 85 |
"2": {
|
| 86 |
"supported_by_embeddings": true,
|
| 87 |
+
"max_similarity": 1.0187240839004517,
|
| 88 |
"evidence": [
|
| 89 |
{
|
| 90 |
+
"idx": 30,
|
| 91 |
+
"page": 16,
|
| 92 |
+
"score": 0.6454246044158936,
|
| 93 |
+
"text": "**5.3.2** **Transformer Encoder**\n\n\n**Mục tiêu** Các lớp Transformer encoder xửlý ma trận embedding đểtạo biểu diễn ngữcảnh sâu sắc\ncho mỗi token, đặc biệt là vector [CLS], giúp nắm bắt mối quan hệgiữa các từtrong tin nhắn. 16"
|
| 94 |
},
|
| 95 |
{
|
| 96 |
+
"idx": 53,
|
| 97 |
+
"page": 17,
|
| 98 |
+
"score": 0.9272838234901428,
|
| 99 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n\n**Cấu trúc** BERT-base có **12 lớp encoder**, mỗi lớp bao gồm:\n\n\n1. **Multi-Head Self-Attention** : Cho phép mỗi token “chú ý” đến các token khác trong chuỗi để\ncập nhật vector của nó. Công thức:\n\n\n\n_QK_ _T_\nAttention( _Q, K, V_ ) = softmax\n� ~~_√_~~ _d_ _k_\n\n\n\n_V_\n�\n\n\n\n\n - _Q_, _K_, _V_ : Ma trận query, key, value, được tạo từma trận embedding qua các trọng số _W_ _Q_,\n_W_ _K_, _W_ _V_ . - _d_ _k_ : Kích thước mỗi head (768 / 12 = 64). - Mỗi lớp có **12 head**, mỗi head xửlý một góc nhìn khác của ngữcảnh. Ví dụ: Trong “Nhận ngay quà tặng miễn phí!”, token “miễn” chú ý mạnh đến “quà” và “tặng”,\ntạo ngữcảnh quảng cáo. Attention Mask đảm bảo không chú ý đến [PAD]. Kết quả: Ma trận 16\n_×_ 768, với mỗi token được cập nhật dựa trên ngữcảnh. 2. **Residual Connection và Layer Normalization** : Cộng đầu vào và đầu ra của attention:\n\n\n_x_ + Attention( _x_ )\n\n\nSau đó chuẩn hóa:\nLayerNorm( _x_ + Attention( _x_ ))\n\n\n3. **Feed-Forward Neural Network (FFN)** : ..."
|
| 100 |
},
|
| 101 |
{
|
| 102 |
+
"idx": 32,
|
| 103 |
+
"page": 28,
|
| 104 |
+
"score": 1.0187240839004517,
|
| 105 |
+
"text": "Các chuỗi này đóng vai trò là ”điểm neo” ngữnghĩa cho mỗi loại. Mô hình BERT\ncũng tạo ra một vector nhúng cho mỗi chuỗi này\n\n\n28"
|
| 106 |
}
|
| 107 |
],
|
| 108 |
"model_verdict": {
|
| 109 |
"supported": true,
|
| 110 |
"confidence": 0.99,
|
| 111 |
+
"evidence": "BERT-base có **12 lớp encoder**",
|
| 112 |
+
"reason": "Context explicitly states BERT-base has 12 encoder layers, matching the answer."
|
| 113 |
}
|
| 114 |
},
|
| 115 |
"3": {
|
| 116 |
"supported_by_embeddings": true,
|
| 117 |
+
"max_similarity": 0.808438777923584,
|
| 118 |
"evidence": [
|
| 119 |
{
|
| 120 |
+
"idx": 14,
|
| 121 |
+
"page": 20,
|
| 122 |
+
"score": 0.7317581176757812,
|
| 123 |
+
"text": "**6.1** **Khung Phân loại Trọng sốĐềxuất**\n\n\nVì vậy nhóm đã nghiên cứu và đềxuất áp dụng công thức trọng sốmới trong quá trình voting của KNN\nbằng kết hợp hai yếu tốtương đồng (similarity) và tầm quan trọng tinh tếcủa từng thực thể(saliency). **6.2** **Công thức Cốt lõi**\n\n\nweight( _x_ _j_ _,_ _q_ ) = (1 _−_ _α_ ) _×_ similarity( _x_ _j_ _,_ _q_ ) _×_ ICF( _y_ ( _x_ _j_ )) + _α ×_ saliency( _x_ _j_ _,_ _q_ ) (5)\n\n\nTrong đó:\n\n\n_x_ _j_ _·_ _q_\nsimilarity( _x_ _j_ _, q_ ) = cos( _x_ _j_ _, q_ ) = (6)\n_∥x_ _j_ _∥× ∥q∥_\n\n\n\n_N_\nICF( _c_ _i_ ) =\n_M × n_ _i_\n\n\n\n(7)\n\n\n\nsaliency( _x_ _j_ _, q_ ) = _∥∇_ _x_ _j_ _L_ ( _f_ ( _x_ _j_ ) _,_ ˆ _y_ ) _∥_ 2 (8)\n\n_α ∈_ [0 _,_ 1] (tham sốcân bằng) (9)\n\n\n**6.3** **Quyết định Phân loại Cuối cùng**\n\n\n\nˆ\n_y_ = arg max\n_c_ _i_ _∈C_\n\n\n\n�\n\n_x_ _j_ _∈N_ _K_ ( _q_ )\n_y_ ( _x_ _j_ )= _c_ _i_\n\n\n20\n\n\n\nweight( _x_ _j_ _, q_ ) (10)"
|
| 124 |
+
},
|
| 125 |
+
{
|
| 126 |
+
"idx": 56,
|
| 127 |
+
"page": 24,
|
| 128 |
+
"score": 0.765610933303833,
|
| 129 |
+
"text": "**6.4.3** **Trọng sốNội dung dựa trên Saliency**\n\n\n**Định nghĩa 3** (Gradient-based Saliency) **.** _Thành phần saliency nắm bắt_ _**tầm quan trọng cụthể**_\n_**theo đầu vào**_ _dựa trên mô hình explainable AI:_\n\n\n_saliency_ ( _x_ _j_ _, q_ ) = _∥∇_ _x_ _j_ _L_ ( _f_ ( _x_ _j_ ) _,_ ˆ _y_ ) _∥_ 2 (38)\n\n\n**6.4.4** **Kết hợp Lồi và Tham sốCân bằng** _α_\n\n\n**Định lý 6.1** (Tính chất Convex Combination) **.** _Tham số_ _α tạo ra_ _**kết hợp lồi**_ _của hai lược đồtrọng_\n_số:_\n\n_weight_ = (1 _−_ _α_ ) _× w_ _similarity×ICF_ + _α × w_ _saliency_ (39)\n\n_Với α ∈_ [0 _,_ 1] _, kết quảnằm trong convex hull của hai thành phần._\n\n\n**6.5** **Phân tích Lý thuyết: Tại sao Công thức này Hợp lý**\n\n\n**6.5.1** **Phân tích Hiệu chỉnh Bias**\n\n\n**Định lý 6.2** (Bias Correction) **.** _Đối với majority voting truyền thống, ảnh hưởng kỳvọng của lớp c_ _i_ _là:_\n\nE[ _Influence_ _traditional_ ( _c_ _i_ )] = _K × P_ ( _c_ _i_ ) = _K ×_ _N_ _[n]_ _[i]_ (40)\n\n\n_Với phương pháp trọng sốcủa chúng ta:_\n\n\nE[ _Influence..."
|
| 130 |
},
|
| 131 |
{
|
| 132 |
+
"idx": 41,
|
| 133 |
+
"page": 19,
|
| 134 |
+
"score": 0.808438777923584,
|
| 135 |
+
"text": "Đối với điểm truy vấn _q_, KNN truyền thống tính toán:\n\n\nˆ\n_y_ = arg max _c_ _i_ _∈C_ _[|{][x]_ _[j]_ _[ ∈N]_ _[K]_ [(] _[q]_ [) :] _[ y]_ [(] _[x]_ _[j]_ [) =] _[ c]_ _[i]_ _[}|]_ (1)\n\n\n**Phân tích Bias:**\nXác suất đểmột K-neighborhood ngẫu nhiên chứa _k_ thực thểtừlớp _c_ _i_ tuân theo phân phối siêu hình\nhọc:\n\n\n19"
|
| 136 |
}
|
| 137 |
],
|
| 138 |
"model_verdict": {
|
| 139 |
"supported": true,
|
| 140 |
+
"confidence": 0.99,
|
| 141 |
+
"evidence": "weight = (1 - α) × w_similarity×ICF + α × w_saliency (39)",
|
| 142 |
+
"reason": "Công thức trong Định lý 6.1 khớp với đáp án đã cho"
|
| 143 |
}
|
| 144 |
},
|
| 145 |
"4": {
|
| 146 |
+
"supported_by_embeddings": true,
|
| 147 |
+
"max_similarity": 0.5541524291038513,
|
| 148 |
+
"evidence": [
|
| 149 |
+
{
|
| 150 |
+
"idx": 21,
|
| 151 |
+
"page": 15,
|
| 152 |
+
"score": 0.5191619992256165,
|
| 153 |
+
"text": "Trong bài toán spam/ham, BERT được tinh\nchỉnh đểtối ưu hóa dựđoán nhãn và tập trung vào các từkhóa quan trọng như “miễn phí” hoặc “quà\ntặng” trong tin nhắn spam. **Ứng dụng** : Trong phân loại tin nhắn spam/ham, BERT chuyển tin nhắn thành vector số, hiểu ngữ\ncảnh sâu sắc (ví dụ: nhận diện ”miễn phí” trong ngữcảnh quảng cáo), và dựđoán nhãn (spam hoặc\nham). **Ưu điểm** :\n\n\n - Hiểu ngữcảnh hai chiều, vượt trội so với các phương pháp truyền thống như TF-IDF. - Sửdụng vector [CLS] đểtổng hợp thông tin toàn câu, phù hợp cho phân loại. **5.3** **Kiến trúc BERT**\n\n\nQuy trình xửlý của BERT bao gồm ba giai đoạn chính:\n\n\n1. **Mã hóa đầu vào** : Chuyển tin nhắn thành token, embedding, và attention mask. 2. **Xửlý qua Transformer encoder** : Tạo biểu diễn ngữcảnh cho từng token, đặc biệt là vector\n\n[CLS]. 3. **Phân loại** : Sửdụng vector [CLS] đểdựđoán nhãn spam/ham. Phần này trình bày chi tiết từng thành phần của kiến trúc BERT và cách chúng hỗtrợbài toán phân\nloại tin nhắn spam/ham. **5.3.1** *..."
|
| 154 |
+
},
|
| 155 |
+
{
|
| 156 |
+
"idx": 57,
|
| 157 |
+
"page": 10,
|
| 158 |
+
"score": 0.5541524291038513,
|
| 159 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n\n2. **Thiếu dữliệu vềspam tinh vi (Subtle or Obfuscated Spam)** :\n\n\n - Phần lớn mẫu spam trong tập train có dạng “truyền thống” — sửdụng từkhóa dễnhận\ndiện như _“FREE!!!”_, _“WIN now”_, _“Click here”_,... - Trong khi đó, spam thực tếngày nay ngày càng được thiết kếtinh vi hơn để **bắt chước văn**\n**phong tựnhiên của người thật**, ví dụ:\n\n\n_“Yo, this app gave me $200 cashback instantly, you should try =«”_\n\n\n - Do thiếu các ví dụkiểu này trong tập huấn luyện, mô hình không có cơ hội học được “ngữ\nnghĩa tiềm ẩn” của chúng, từđó dễbịđánh lừa. **2.2** **Giải pháp: Data Augmentation**\n\n\n**Mục tiêu**\n\n\nTăng độđa dạng của spam, đặc biệt là spam có dạng giống ham, nhằm:\n\n\n - Cân bằng dữliệu một cách hiệu quả\n\n\n - Tăng khảnăng mô hình phát hiện spam ngụy trang và những câu ham dễnhầm thành spam\n\n\n**Mô tảthay đổi của dataset trước và sau Augmentation**\n\n\nDataset gốc là _SMS Spam Collection Dataset_ từKaggle, có tổng cộng 5.572 tin nhắn, trong đó có 4.82..."
|
| 160 |
+
}
|
| 161 |
+
],
|
| 162 |
"model_verdict": {
|
| 163 |
+
"supported": true,
|
| 164 |
+
"confidence": 0.99,
|
| 165 |
+
"evidence": "Không hiểu ngữcảnh: Không thể phân biệt được ý nghĩa của một từ trong các ngữcảnh khác nhau.",
|
| 166 |
+
"reason": "Context explicitly lists 'Không hiểu ngữcảnh' as a disadvantage of keyword-based spam detection."
|
| 167 |
}
|
| 168 |
},
|
| 169 |
"5": {
|
| 170 |
"supported_by_embeddings": true,
|
| 171 |
+
"max_similarity": 1.0499497652053833,
|
| 172 |
"evidence": [
|
| 173 |
{
|
| 174 |
+
"idx": 53,
|
| 175 |
+
"page": 17,
|
| 176 |
+
"score": 0.7536194324493408,
|
| 177 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n\n**Cấu trúc** BERT-base có **12 lớp encoder**, mỗi lớp bao gồm:\n\n\n1. **Multi-Head Self-Attention** : Cho phép mỗi token “chú ý” đến các token khác trong chuỗi để\ncập nhật vector của nó. Công thức:\n\n\n\n_QK_ _T_\nAttention( _Q, K, V_ ) = softmax\n� ~~_√_~~ _d_ _k_\n\n\n\n_V_\n�\n\n\n\n\n - _Q_, _K_, _V_ : Ma trận query, key, value, được tạo từma trận embedding qua các trọng số _W_ _Q_,\n_W_ _K_, _W_ _V_ . - _d_ _k_ : Kích thước mỗi head (768 / 12 = 64). - Mỗi lớp có **12 head**, mỗi head xửlý một góc nhìn khác của ngữcảnh. Ví dụ: Trong “Nhận ngay quà tặng miễn phí!”, token “miễn” chú ý mạnh đến “quà” và “tặng”,\ntạo ngữcảnh quảng cáo. Attention Mask đảm bảo không chú ý đến [PAD]. Kết quả: Ma trận 16\n_×_ 768, với mỗi token được cập nhật dựa trên ngữcảnh. 2. **Residual Connection và Layer Normalization** : Cộng đầu vào và đầu ra của attention:\n\n\n_x_ + Attention( _x_ )\n\n\nSau đó chuẩn hóa:\nLayerNorm( _x_ + Attention( _x_ ))\n\n\n3. **Feed-Forward Neural Network (FFN)** : ..."
|
| 178 |
+
},
|
| 179 |
+
{
|
| 180 |
+
"idx": 50,
|
| 181 |
+
"page": 7,
|
| 182 |
+
"score": 1.0445164442062378,
|
| 183 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n\n**Explainable AI (XAI) và Classifier:**\n\n\n **Vấn đềtồn đọng:** Mô hình hoạt động như một ”hộp đen”, khó giải thích lý do đưa ra dựđoán. Khảnăng giải thích thường bịtách rời khỏi quá trình phân loại chính. **Giải pháp:** Tích hợp khảnăng giải thích vào lõi của bộphân loại. **–**\n_Masking-based Saliency:_ Phương pháp này xác định các từkhóa quan trọng nhất trong tin\nnhắn. Nói trực quan thì từnào quan trọng trong quyết định spam hơn sẽđược tô đậm hơn. **–**\n_Phân loại có tích hợp Saliency:_ Bộphân loại sửdụng một tham số‘alpha‘ đểđiều chỉnh mức\nđộảnh hưởng của điểm nổi bật (saliency score) vào công thức phân loại cuối cùng, giúp kết\nquảchính xác hơn và có thểgiải thích được. **Đầu ra cuối cùng:** Đầu ra cho mỗi câu gồm thông tin dựđoán và chỉsốgiải thích cho dựđoán đó,\ngiúp người dùng hiểu rõ quyết định của mô hình. Cấu trúc đầu ra bao gồm:\n\n\n - **Lớp dựđoán:** Tin nhắn được gán nhãn dựđoán cuối cùng ( _SPAM_ hoặc _HAM_ ) dựa trên kết quả\nphân loại. *..."
|
| 184 |
},
|
| 185 |
{
|
| 186 |
+
"idx": 42,
|
| 187 |
+
"page": 18,
|
| 188 |
+
"score": 1.0499497652053833,
|
| 189 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n\n**Kết quả** Sau 12 lớp encoder, mỗi token có vector 768 chiều, chứa thông tin ngữcảnh sâu sắc. Vector\n\n[CLS] (hàng đầu tiên của ma trận đầu ra) tổng hợp ngữcảnh toàn tin nhắn, ví dụ: `[0.7, -0.1, ...,`\n`0.5]`, phản ánh đặc trưng spam như “miễn phí”, “quà”. **Liên hệvới spam/ham** Attention giúp BERT nhận diện mối quan hệgiữa các từ(như “miễn phí”\nvà “quà” gợi ý spam). FFN tinh chỉnh vector đểnhấn mạnh đặc trưng riêng của mỗi token, hỗtrợ\nvector [CLS] mang thông tin quảng cáo hoặc giao tiếp tựnhiên. **5.3.3** **Lớp Phân Loại**\n\n\n**Mục tiêu** Sửdụng vector [CLS] đểdựđoán nhãn spam (1) hoặc ham (0) cho tin nhắn. **Quy trình**\n\n\n1. **Lớp tuyến tính** : Vector [CLS] (768 chiều) được đưa qua lớp tuyến tính:\n\n\nlogits = _W_ cls _·_ vector [CLS] + _b_ cls\n\n\n - _W_ cls : Ma trận 768 _×_ 2 (2 nhãn: spam, ham). - _b_ cls : Bias 2 chiều. Ví dụ: Vector [CLS] `[0.7, -0.1, ..., 0.5]` _→_ Logits `[2.8, -0.7]` . 2. **Softmax** : Chuyển logits thành xác suất:\n\n\nexp(..."
|
| 190 |
}
|
| 191 |
],
|
| 192 |
"model_verdict": {
|
| 193 |
"supported": true,
|
| 194 |
"confidence": 0.99,
|
| 195 |
+
"evidence": "BERT-base có 12 lớp encoder ... Mỗi lớp có 12 head ... mỗi token có vector 768 chiều",
|
| 196 |
+
"reason": "Context xác nhận BERT-base có 12 lớp encoder, hidden size 768 và 12 attention head, nên đáp án a được chứng thực."
|
| 197 |
}
|
| 198 |
}
|
| 199 |
}
|
test/oop_mcq_output.json
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"mcqs": {
|
| 3 |
+
"1": {
|
| 4 |
+
"câu hỏi": "Trong ví dụ minh họa lớp Cat, khi gọi cat.describe(2), dòng lệnh `print(self.age)` sẽ in ra giá trị nào?",
|
| 5 |
+
"lựa chọn": {
|
| 6 |
+
"a": "2 (giá trị truyền vào hàm, là biến cục bộ)",
|
| 7 |
+
"b": "1 (giá trị của biến lớp)",
|
| 8 |
+
"c": "Lỗi vì self.age không được định nghĩa",
|
| 9 |
+
"d": "0 (giá trị mặc định của biến toàn cục)"
|
| 10 |
+
},
|
| 11 |
+
"đáp án": "1 (giá trị của biến lớp)"
|
| 12 |
+
},
|
| 13 |
+
"2": {
|
| 14 |
+
"câu hỏi": "Theo nội dung trên, biến nào được mô tả là “thông tin tuyệt mật – chỉ lớp khai báo nó mới có quyền truy cập”?",
|
| 15 |
+
"lựa chọn": {
|
| 16 |
+
"a": "private",
|
| 17 |
+
"b": "protected",
|
| 18 |
+
"c": "public",
|
| 19 |
+
"d": "static"
|
| 20 |
+
},
|
| 21 |
+
"đáp án": "private"
|
| 22 |
+
},
|
| 23 |
+
"3": {
|
| 24 |
+
"câu hỏi": "Biến cục bộ (local variable) trong lập trình hướng đối tượng có đặc điểm nào sau đây?",
|
| 25 |
+
"lựa chọn": {
|
| 26 |
+
"a": "Có thể truy cập ở bất kỳ đâu trong chương trình",
|
| 27 |
+
"b": "Chỉ tồn tại và có thể sử dụng trong một hàm hoặc phương thức cụ thể",
|
| 28 |
+
"c": "Là biến toàn cục được khai báo bên ngoài hàm",
|
| 29 |
+
"d": "Biến được tự động khởi tạo giá trị mặc định"
|
| 30 |
+
},
|
| 31 |
+
"đáp án": "Chỉ tồn tại và có thể sử dụng trong một hàm hoặc phương thức cụ thể"
|
| 32 |
+
},
|
| 33 |
+
"4": {
|
| 34 |
+
"câu hỏi": "Trong lập trình hướng đối tượng, thuộc tính (attributes) của một đối tượng là gì?",
|
| 35 |
+
"lựa chọn": {
|
| 36 |
+
"a": "Các hàm thực hiện hành động của đối tượng",
|
| 37 |
+
"b": "Các biến lưu trữ dữ liệu mô tả đối tượng",
|
| 38 |
+
"c": "Các lớp mà đối tượng kế thừa từ chúng",
|
| 39 |
+
"d": "Các phương thức tĩnh không phụ thuộc vào đối tượng"
|
| 40 |
+
},
|
| 41 |
+
"đáp án": "Các biến lưu trữ dữ liệu mô tả đối tượng"
|
| 42 |
+
},
|
| 43 |
+
"5": {
|
| 44 |
+
"câu hỏi": "Trong Python, phương thức đặc biệt nào cho phép một đối tượng được gọi như một hàm?",
|
| 45 |
+
"lựa chọn": {
|
| 46 |
+
"a": "__init__",
|
| 47 |
+
"b": "__str__",
|
| 48 |
+
"c": "__call__",
|
| 49 |
+
"d": "__len__"
|
| 50 |
+
},
|
| 51 |
+
"đáp án": "__call__"
|
| 52 |
+
}
|
| 53 |
+
},
|
| 54 |
+
"validation": {
|
| 55 |
+
"1": {
|
| 56 |
+
"supported_by_embeddings": true,
|
| 57 |
+
"max_similarity": 1.0644214153289795,
|
| 58 |
+
"evidence": [
|
| 59 |
+
{
|
| 60 |
+
"idx": 1,
|
| 61 |
+
"page": 1,
|
| 62 |
+
"score": 0.6182047724723816,
|
| 63 |
+
"text": "**Biến cục bộ(Local)**\n\n\nBiến cục bộchỉtồn tại và có thểsửdụng trong một hàm hoặc phương thức cụthể. **Quy tắc ưu tiên (Scope resolution):**\n\n\nLocal _>_ Instance _>_ Class _>_ Global (1)\n\n\n**Ví dụminh họa:**\n\n\n1 `class Cat():`\n\n\n2 `age = 1 #Class variabe`\n\n3 `def describe(self, age):`\n\n4 `print(age, age)` `# Ouput: 2,2 (both are local variables)`\n\n5 `print(self.age)` `# Output: 1 (class variable)`\n\n\n6\n\n\n7 `cat = Cat()`\n\n\n8 `cat.describe(2)`\n\n\n1"
|
| 64 |
+
},
|
| 65 |
+
{
|
| 66 |
+
"idx": 2,
|
| 67 |
+
"page": 2,
|
| 68 |
+
"score": 0.9349313378334045,
|
| 69 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n\nCảhai biến age ởlần in đầu tiên đều là biến cục bộvì Python sẽưu tiên tìm biến cục bộtrước,\nởđây là đối số2 truyền vào age. Vì ta không định nghĩa self.age, nên khi gọi, Python sẽtìm đến\nthứtựtiếp theo là biến Class. Chính vì vậy, ta sẽin ra được kết quảage = 1\n\n\n**1.1.2** **Biến toàn cục (Global)**\n\n\nBiến toàn cục được khai báo bên ngoài hàm hoặc class, sửdụng được trên toàn chương trình\nnhưng nên hạn chếđểtránh gây khó kiểm soát. **Không khuyến khích:**\n\n\n1 `counter = 0` `# Global variable`\n\n\n2\n\n\n3 `class MyClass:`\n\n4 `def increment(self):`\n\n\n5 `global counter`\n\n\n6 `counter += 1`\n\n\n**Khuyến khích:**\n\n\n1 `class MyClass:`\n\n\n2 `counter = 0` `# Class attribute`\n\n\n3\n\n\n4 `def increment(self):`\n\n\n5 `MyClass.counter += 1`\n\n### **2 Động lực cho sựra đời của OOP**\n\n\nTrong thực tế, chúng ta luôn tìm cách mô hình hóa các thực thểthực tếthành các đối tượng số\nhóa. Từnhu cầu quản lý và tổchức các thực thểnày, lập trình hướng đối tượng ra đời đểđơn\ngiản hóa và ..."
|
| 70 |
+
},
|
| 71 |
+
{
|
| 72 |
+
"idx": 8,
|
| 73 |
+
"page": 5,
|
| 74 |
+
"score": 1.0644214153289795,
|
| 75 |
+
"text": "es a function →Output: Hi Alice`\n\n\n2. **Stateful function** : Hàm có thểghi nhớtrạng thái bên trong. 1 `class Counter:`\n\n\n2 `def __init__(self):`\n\n\n3 `self.count = 0`\n\n\n4\n\n\n5 `def __call__(self):`\n\n\n6 `self.count += 1`\n\n\n7 `return self.count`\n\n\n8\n\n\n9 `counter = Counter()`\n\n\n10\n\n\n11 `print(counter())` `# 1`\n\n12 `print(counter())` `# 2`\n\n13 `print(counter())` `# 3`\n\n\nMỗi lần gọi `counter()` đều ghi nhớtrạng thái trước đó và cộng dồn lên, không giống như\ncác phương thức thông thường vốn không lưu trạng thái giữa các lần gọi. 3. **Decorator hoặc Callback handler** : (nâng cao cần tìm hiểu thêm). ## **Phần II: Các tính chất cơ bản trong Object-** **Oriented Programming**\n\n### **5** **Delegation (Ủy quyền)**\n\n\nDelegation (ủy quyền) trong lập trình hướng đối tượng là một kỹthuật trong đó một đối tượng\nủy thác trách nhiệm thực hiện một hành vi cụthểcho một đối tượng khác. Thay vì kếthừa trực\n\n\n5"
|
| 76 |
+
}
|
| 77 |
+
],
|
| 78 |
+
"model_verdict": {
|
| 79 |
+
"supported": true,
|
| 80 |
+
"confidence": 0.99,
|
| 81 |
+
"evidence": "print(self.age) # Output: 1 (class variable)",
|
| 82 |
+
"reason": "Context explicitly states that print(self.age) outputs 1, the class variable."
|
| 83 |
+
}
|
| 84 |
+
},
|
| 85 |
+
"2": {
|
| 86 |
+
"supported_by_embeddings": true,
|
| 87 |
+
"max_similarity": 1.3231226205825806,
|
| 88 |
+
"evidence": [
|
| 89 |
+
{
|
| 90 |
+
"idx": 15,
|
| 91 |
+
"page": 8,
|
| 92 |
+
"score": 1.0267785787582397,
|
| 93 |
+
"text": "p con của nó đều phải **bắt buộc** có phương thức tính diện\ntích. Nếu không, chương trình sẽbáo lỗi. ### **8 Encapsulation (Đóng gói)**\n\n\nTính đóng gói giúp thông tin nội bộcủa đối tượng và chỉcho phép truy cập qua phương thức\ncông khai (public methods). Điều này giúp bảo vệdữliệu và kiểm soát cách dữliệu bịthay đổi. **Ví dụminh họa:**\n\n\n1 `class BankAccount:`\n\n\n2 `def __init__(self, owner, balance):`\n\n\n3 `self.owner = owner`\n\n\n4 `self.__balance = balance` `# \"__\" indicates this is a private attribute`\n\n\n5\n\n\n6 `def deposit(self, amount):`\n\n\n7 `if amount > 0:`\n\n\n8 `self.__balance += amount`\n\n9 `print(f\"Deposited: {amount}\")`\n\n\n10 `else:`\n\n\n11 `print(\"Invalid deposit amount.\")`\n\n\n12\n\n\n13 `def withdraw(self, amount):`\n\n\n14 `if 0 < amount <= self.__balance:`\n\n\n15 `self.__balance -= amount`\n\n\n8"
|
| 94 |
+
},
|
| 95 |
+
{
|
| 96 |
+
"idx": 4,
|
| 97 |
+
"page": 3,
|
| 98 |
+
"score": 1.3231226205825806,
|
| 99 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n\nTương tự:\nGiảsửbạn là một người quản lý thư viện. Trong đó, sách và người đọc chính là những đối tượng\n(objects), còn các quy trình như mượn sách, trảsách, đăng ký thẻđược xem là phương thức\n(methods) – tức là hành vi của các đối tượng. Đểcó thểquản lý hiệu quảtất cảcác đối tượng\nvà hành vi trong hệthống thư viện này, ta cần một cách tổchức logic và linh hoạt. Chính từ\nnhu cầu đó, lập trình hướng đối tượng (OOP) ra đời – như một phương pháp giúp mô hình hóa\nthếgiới thực thành các thành phần trong phần mềm một cách rõ ràng và dễmởrộng.\n\n### **3 Class và Object**\n\n#### **3.1 Class (Lớp)**\n\n\nClass như một bản vẽkỹthuật hoặc template, dùng đểđịnh nghĩa thuộc tính (attributes) và\nphương thức (methods) của các đối tượng.\n\n - **Attributes:** định nghĩa các thông tin, đặc điểm cũng như các thuộc tính của Object.\n\n\n - **Method** : định nghĩa các hành vi, phương thức cũng như các hành động thường có của\nObject\n\n\n3"
|
| 100 |
+
}
|
| 101 |
+
],
|
| 102 |
+
"model_verdict": {
|
| 103 |
+
"supported": true,
|
| 104 |
+
"confidence": 0.99,
|
| 105 |
+
"evidence": "\"Biến `private` là thông tin tuyệt mật – chỉ lớp khai báo nó mới có quyền truy cập\"",
|
| 106 |
+
"reason": "Context explicitly mô tả biến private như vậy, nên đáp án private được chứng thực."
|
| 107 |
+
}
|
| 108 |
+
},
|
| 109 |
+
"3": {
|
| 110 |
+
"supported_by_embeddings": true,
|
| 111 |
+
"max_similarity": 1.127091884613037,
|
| 112 |
+
"evidence": [
|
| 113 |
+
{
|
| 114 |
+
"idx": 1,
|
| 115 |
+
"page": 1,
|
| 116 |
+
"score": 0.8878949880599976,
|
| 117 |
+
"text": "**Biến cục bộ(Local)**\n\n\nBiến cục bộchỉtồn tại và có thểsửdụng trong một hàm hoặc phương thức cụthể. **Quy tắc ưu tiên (Scope resolution):**\n\n\nLocal _>_ Instance _>_ Class _>_ Global (1)\n\n\n**Ví dụminh họa:**\n\n\n1 `class Cat():`\n\n\n2 `age = 1 #Class variabe`\n\n3 `def describe(self, age):`\n\n4 `print(age, age)` `# Ouput: 2,2 (both are local variables)`\n\n5 `print(self.age)` `# Output: 1 (class variable)`\n\n\n6\n\n\n7 `cat = Cat()`\n\n\n8 `cat.describe(2)`\n\n\n1"
|
| 118 |
+
},
|
| 119 |
+
{
|
| 120 |
+
"idx": 0,
|
| 121 |
+
"page": 1,
|
| 122 |
+
"score": 1.107263207435608,
|
| 123 |
+
"text": "# Tuần 3: Tổng hợp kiến thức buổi học số3 + 4\n\n#### Time-Series Team Ngày 21 tháng 6 năm 2025\n\n\n\n\n## **Phần I: Khái niệm cơ bản vềObject-Oriented** **Programming: Lập tr��nh hướng đối tượng**\n\n### **1** **Giới thiệu vềlập trình hướng đối tượng**\n\nLập trình hướng đối tượng (OOP) là một phương pháp lập trình phổbiến, lấy các đối tượng làm\ntrung tâm đểgiải quyết vấn đềthực tế. Đểhiểu rõ OOP, ta cần nắm các khái niệm cơ bản như\nphạm vi biến, trừu tượng hóa, lớp, đối tượng và các tính chất đặc trưng như kếthừa, đa hình,\nđóng gói và trừu tượng. #### **1.1** **Bước đầu cho OOP - Khái niệm biến local và global (biến cục bộ** **và biến toàn cục)**\n\n\nPhạm vi (scope) biến là yếu tốquan trọng trong lập trình, quyết định nơi một biến có thểtruy\ncập được. **1.1.1** **Biến cục bộ(Local)**\n\n\nBiến cục bộchỉtồn tại và có thểsửdụng trong một hàm hoặc phương thức cụthể."
|
| 124 |
+
},
|
| 125 |
+
{
|
| 126 |
+
"idx": 9,
|
| 127 |
+
"page": 6,
|
| 128 |
+
"score": 1.127091884613037,
|
| 129 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n\ntiếp hoặc xửlý toàn bộlogic nội bộ, đối tượng sẽgọi đến phương thức của một thành phần bên\ntrong đểthực hiện nhiệm vụ. Kỹthuật này giúp tách biệt trách nhiệm giữa các lớp, dễbảo trì\nvà mởrộng hệthống và tăng tính tái sửdụng của mã nguồn."
|
| 130 |
+
}
|
| 131 |
+
],
|
| 132 |
+
"model_verdict": {
|
| 133 |
+
"supported": true,
|
| 134 |
+
"confidence": 0.99,
|
| 135 |
+
"evidence": "Biến cục bộ chỉ tồn tại và có thể sử dụng trong một hàm hoặc phương thức cụ thể.",
|
| 136 |
+
"reason": "Câu trả lời khớp với mô tả trong Context về đặc điểm của biến cục bộ."
|
| 137 |
+
}
|
| 138 |
+
},
|
| 139 |
+
"4": {
|
| 140 |
+
"supported_by_embeddings": true,
|
| 141 |
+
"max_similarity": 1.02956223487854,
|
| 142 |
+
"evidence": [
|
| 143 |
+
{
|
| 144 |
+
"idx": 5,
|
| 145 |
+
"page": 4,
|
| 146 |
+
"score": 0.7977743148803711,
|
| 147 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n#### **3.2** **Object (Đối tượng)**\n\n\nObject là một thực thểcụthểđược tạo ra từclass, chứa các giá trịthuộc tính cụthểvà khả\nnăng thực hiện các phương thức đã định nghĩa. ### **4 Cách tạo một Class**\n\n\nMột class diagram bao gồm: tên class, attributes, và methods. Sau khi khởi tạo, ta tạo ra một\nobject là instance của class vừa tạo. **Constructor (** **`__init__`** **):** được dùng đểtạo và gán giá trịban đầu cho các thuộc tính (attributes)\ncủa đối tượng.Nói một cách đơn giản, constructor giống như bản thiết kếban đầu giúp ta xác\nđịnh: ”Khi tạo ra một đối tượng mới, nó sẽcó những thông tin gì?”\n\n\n**Self keyword:** Là tham chiếu đến instance cụthểcủa class. **Ví dụ:**\n\n\n1 `class Rectangle:`\n\n2 `def __init__(self, width, height):`\n\n\n3 `self.width = width`\n\n\n4 `self.height = height`\n\n\n5\n\n\n6 `def area(self):`\n\n\n7 `return self.width * self.height`\n\n\n8\n\n\n9 `my_rec = Rectangle(4, 7)`\n\n10 `print(my_rec.area())` `# Output: 28`\n\n\nTa hình dung “self” là một vùn..."
|
| 148 |
+
},
|
| 149 |
+
{
|
| 150 |
+
"idx": 0,
|
| 151 |
+
"page": 1,
|
| 152 |
+
"score": 1.02956223487854,
|
| 153 |
+
"text": "# Tuần 3: Tổng hợp kiến thức buổi học số3 + 4\n\n#### Time-Series Team Ngày 21 tháng 6 năm 2025\n\n\n\n\n## **Phần I: Khái niệm cơ bản vềObject-Oriented** **Programming: Lập trình hướng đối tượng**\n\n### **1** **Giới thiệu vềlập trình hướng đối tượng**\n\nLập trình hướng đối tượng (OOP) là một phương pháp lập trình phổbiến, lấy các đối tượng làm\ntrung tâm đểgiải quyết vấn đềthực tế. Đểhiểu rõ OOP, ta cần nắm các khái niệm cơ bản như\nphạm vi biến, trừu tượng hóa, lớp, đối tượng và các tính chất đặc trưng như kếthừa, đa hình,\nđóng gói và trừu tượng. #### **1.1** **Bước đầu cho OOP - Khái niệm biến local và global (biến cục bộ** **và biến toàn cục)**\n\n\nPhạm vi (scope) biến là yếu tốquan trọng trong lập trình, quyết định nơi một biến có thểtruy\ncập được. **1.1.1** **Biến cục bộ(Local)**\n\n\nBiến cục bộchỉtồn tại và có thểsửdụng trong một hàm hoặc phương thức cụthể."
|
| 154 |
+
}
|
| 155 |
+
],
|
| 156 |
+
"model_verdict": {
|
| 157 |
+
"supported": true,
|
| 158 |
+
"confidence": 0.98,
|
| 159 |
+
"evidence": "Những thông tin như ngày sinh, giới tính, sốđiện thoại... được xem là thuộc tính (attributes) của người dùng đó.",
|
| 160 |
+
"reason": "Context mô tả thuộc tính là các thông tin dữ liệu mô tả đối tượng, khớp với đáp án."
|
| 161 |
+
}
|
| 162 |
+
},
|
| 163 |
+
"5": {
|
| 164 |
+
"supported_by_embeddings": true,
|
| 165 |
+
"max_similarity": 1.0307352542877197,
|
| 166 |
+
"evidence": [
|
| 167 |
+
{
|
| 168 |
+
"idx": 5,
|
| 169 |
+
"page": 4,
|
| 170 |
+
"score": 0.9137221574783325,
|
| 171 |
+
"text": "**AI VIETNAM** **aivietnam.edu.vn**\n\n#### **3.2** **Object (Đối tượng)**\n\n\nObject là một thực thểcụthểđược tạo ra từclass, chứa các giá trịthuộc tính cụthểvà khả\nnăng thực hiện các phương thức đã định nghĩa. ### **4 Cách tạo một Class**\n\n\nMột class diagram bao gồm: tên class, attributes, và methods. Sau khi khởi tạo, ta tạo ra một\nobject là instance của class vừa tạo. **Constructor (** **`__init__`** **):** được dùng đểtạo và gán giá trịban đầu cho các thuộc tính (attributes)\ncủa đối tượng.Nói một cách đơn giản, constructor giống như bản thiết kếban đầu giúp ta xác\nđịnh: ”Khi tạo ra một đối tượng mới, nó sẽcó những thông tin gì?”\n\n\n**Self keyword:** Là tham chiếu đến instance cụthểcủa class. **Ví dụ:**\n\n\n1 `class Rectangle:`\n\n2 `def __init__(self, width, height):`\n\n\n3 `self.width = width`\n\n\n4 `self.height = height`\n\n\n5\n\n\n6 `def area(self):`\n\n\n7 `return self.width * self.height`\n\n\n8\n\n\n9 `my_rec = Rectangle(4, 7)`\n\n10 `print(my_rec.area())` `# Output: 28`\n\n\nTa hình dung “self” là một vùn..."
|
| 172 |
+
},
|
| 173 |
+
{
|
| 174 |
+
"idx": 3,
|
| 175 |
+
"page": 2,
|
| 176 |
+
"score": 1.0307352542877197,
|
| 177 |
+
"text": "gười dùng chính là một đối tượng (object). Những thông tin như ngày sinh, giới tính, sốđiện thoại... được xem là thuộc tính (attributes)\ncủa người dùng đó. Còn các hành vi như đăng bài, thích (like), chia sẻ(share), bình luận, kết\nbạn... chính là những phương thức (methods) – tức là hành động mà đối tượng đó có thểthực\nhiện. Đây chính là cách mà lập trình hướng đối tượng mô hình hóa và tổchức các thực thểtrong\nthếgiới số. 2"
|
| 178 |
+
}
|
| 179 |
+
],
|
| 180 |
+
"model_verdict": {
|
| 181 |
+
"supported": true,
|
| 182 |
+
"confidence": 0.99,
|
| 183 |
+
"evidence": "Trong Python, `__call__` là một phương thức đặc biệt ... được sửdụng khi một đối tượng cần hành xử giống như một hàm. Nếu một lớp định nghĩa `__call__`, thì các instance của lớp đó có thể được gọi như một hàm thực sự.",
|
| 184 |
+
"reason": "Context explicitly states that __call__ is the special method allowing objects to be called like functions."
|
| 185 |
+
}
|
| 186 |
+
}
|
| 187 |
+
}
|
| 188 |
+
}
|
test/output.json
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
test/politic_mcq_output.json
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"mcqs": {
|
| 3 |
+
"1": {
|
| 4 |
+
"câu hỏi": "Theo nội dung, tính chất chính trị của tôn giáo chỉ xuất hiện khi nào?",
|
| 5 |
+
"lựa chọn": {
|
| 6 |
+
"a": "Khi xã hội không có giai cấp và không có xung đột lợi ích",
|
| 7 |
+
"b": "Khi xã hội đã phân chia giai cấp, có sự khác biệt, sự đối kháng về lợi ích",
|
| 8 |
+
"c": "Khi tôn giáo được nhà nước kiểm soát chặt chẽ",
|
| 9 |
+
"d": "Khi nền kinh tế phát triển mạnh và không có bất bình xã hội"
|
| 10 |
+
},
|
| 11 |
+
"đáp án": "Khi xã hội đã phân chia giai cấp, có sự khác biệt, sự đối kháng về lợi ích"
|
| 12 |
+
},
|
| 13 |
+
"2": {
|
| 14 |
+
"câu hỏi": "Theo nội dung, giai cấp công nhân hiện đại bao gồm những nhóm nào sau đây?",
|
| 15 |
+
"lựa chọn": {
|
| 16 |
+
"a": "Là sản phẩm và chủ thể của nền đại công nghiệp.",
|
| 17 |
+
"b": "Là nguồn nhân lực chủ yếu tham gia phát triển kinh tế thị trường định hướng XHCN.",
|
| 18 |
+
"c": "Bao gồm giai cấp nông dân và thợ thủ công.",
|
| 19 |
+
"d": "Được đại diện bởi Đảng Cộng sản."
|
| 20 |
+
},
|
| 21 |
+
"đáp án": "Bao gồm giai cấp nông dân và thợ thủ công."
|
| 22 |
+
},
|
| 23 |
+
"3": {
|
| 24 |
+
"câu hỏi": "Theo nội dung trên, yếu tố nào được nêu là một trong những điều kiện kinh tế để chủ nghĩa xã hội ra đời?",
|
| 25 |
+
"lựa chọn": {
|
| 26 |
+
"a": "Sự phát triển của công nghiệp cơ khí",
|
| 27 |
+
"b": "Sự giảm chênh lệch giàu nghèo",
|
| 28 |
+
"c": "Sự tồn tại của nền kinh tế kế hoạch",
|
| 29 |
+
"d": "Sự tăng trưởng của nông nghiệp truyền thống"
|
| 30 |
+
},
|
| 31 |
+
"đáp án": "Sự phát triển của công nghiệp cơ khí"
|
| 32 |
+
},
|
| 33 |
+
"4": {
|
| 34 |
+
"câu hỏi": "Theo nội dung trên, trong các đặc trưng bản chất của chủ nghĩa xã hội do Mác nêu, đặc điểm nào sau đây không được liệt kê?",
|
| 35 |
+
"lựa chọn": {
|
| 36 |
+
"a": "Có nền kinh tế phát triển cao",
|
| 37 |
+
"b": "Có nhà nước kiểu mới mang bản chất GCCN",
|
| 38 |
+
"c": "Có nền văn hóa phát triển cao",
|
| 39 |
+
"d": "Có hệ thống chính trị đa đảng"
|
| 40 |
+
},
|
| 41 |
+
"đáp án": "Có hệ thống chính trị đa đảng"
|
| 42 |
+
},
|
| 43 |
+
"5": {
|
| 44 |
+
"câu hỏi": "Theo quan điểm cơ bản của Marx‑Lenin, sứ mệnh lịch sử của Cách mạng xã hội chủ nghĩa (CNXH) là gì?",
|
| 45 |
+
"lựa chọn": {
|
| 46 |
+
"a": "Sự phát triển kinh tế nhanh chóng",
|
| 47 |
+
"b": "Sứ mệnh lịch sử là những nhiệm vụ quan trọng, thiêng liêng buộc phải thực hiện trong một điều kiện, hoàn cảnh lịch sử cụ thể nhất định",
|
| 48 |
+
"c": "Tăng cường quan hệ quốc tế",
|
| 49 |
+
"d": "Đảm bảo quyền lợi cá nhân"
|
| 50 |
+
},
|
| 51 |
+
"đáp án": "Sứ mệnh lịch sử là những nhiệm vụ quan trọng, thiêng liêng buộc phải thực hiện trong một điều kiện, hoàn cảnh lịch sử cụ thể nhất định"
|
| 52 |
+
}
|
| 53 |
+
},
|
| 54 |
+
"validation": {
|
| 55 |
+
"1": {
|
| 56 |
+
"supported_by_embeddings": true,
|
| 57 |
+
"max_similarity": 0.7614468336105347,
|
| 58 |
+
"evidence": [
|
| 59 |
+
{
|
| 60 |
+
"idx": 45,
|
| 61 |
+
"page": 23,
|
| 62 |
+
"score": 0.7614468336105347,
|
| 63 |
+
"text": "Nguồn gốc nhân thức\nNguồn gốc tâm lí\n\n##### **Tính chất của tôn giáo**\n\n\n Các điều kiện kinh tế-xã hội là cho các tôn giáo bịphân liệt, chia rẽ\n\n Các tôn giáo là nơi sinh hoạt văn hóa tinh thần của một cộng đồng\n\n TÍnh chất chính trịcủa tôn giáo chỉxuất hiện khi xã hội đã phân chia giai cấp,\ncó sựkhác biệt, sựđối kháng vềlợi ích. ##### **Nguyên tắc trong giải quyết vấn đềtôn giáo**\n\n\n Tôn trọng, đảm bảo quyền tựdo tín ngưỡng và không tín ngưỡng của nhân\n\ndân\n\n Khắc phục dần những ảnh hưởng tiêu cực của tôn giáo phải gắn liền với quá\ntrình cỉa tạo xã hội cũ, xây dựng xa hội mới."
|
| 64 |
+
},
|
| 65 |
+
{
|
| 66 |
+
"idx": 23,
|
| 67 |
+
"page": 23,
|
| 68 |
+
"score": 0.7602448463439941,
|
| 69 |
+
"text": "Phân biệt hai mặt chính trịvà tư tưởng, tín ngưỡng tôn giáo và lợi dụng tín\nngưỡng tôn giáo\n\n Quan điểm lịch sửcụthểtrong giải quyết vấn đềtín ngưỡng, tôn giáo\n\n##### **Tác động của tôn giáo**\n\n\n Khuyến khích đoàn kết, khoan dung giữa các tôn giáo, phát huy các giá trịtốt\nđẹp của tôn giáo\n\n Có vai trò xây dựng đối với xã hội và đóng góp những giá trịtốt đẹp\n\n Kênh quan trọng đểthúc đẩy mởrộng đối ngoại\n\n Phòng chống xung đột, kiến tạo hòa bình, quản trịxã hội\nTác hại tiêu cực của tôn giáo: phương hại đến chính sách tựdo tìn ngưỡng, nhân\nthức thái quá và sai lệch vềĐảng và nhà nước, thu tiền trái phép\n\n##### **Chính sách của Đảng và nhà nước**\n\n\n - Là nhu cầu tinh thần\n\n Tôn trọng quyền tựdo, tín ngưỡng, thực hiện chính sách đại đoàn kết là chính\nsách nhất quán, xuyên suốt của Đảng\n\n##### **Phương hướng hoạt động trong thời gian tới**\n\n\n Một, thực hiện hiệu quảchủtrương, chính sách đầu tư phát triển\n\n Nâng cao thống nhất quan điểm chỉđạo\n\n Tăng cường công tác kiểm tra\n\n Tiếp ..."
|
| 70 |
+
},
|
| 71 |
+
{
|
| 72 |
+
"idx": 30,
|
| 73 |
+
"page": 24,
|
| 74 |
+
"score": 0.6624355316162109,
|
| 75 |
+
"text": "Khi tôn giáo xây dựng thành công CNXH thì còn tôn giáo không? Vẫn có vấn đềkhông giái thích được\n\n Vẫn có người tin thì vẫn còn tồn tại\n\n Là một phần trong nhu cầu cơ bản thiết yếu của con người\n\n Điều kiện tồn tại của tôn giáo còn trên khách quan như cơ chếthịtrường\n(muốn xóa bỏtôn gióa phải xóa bỏdc…)\n\n##### **Sựkhác nhau tín ngưỡng và tôn giáo**\n\n\nTôn giáo phải có hệthống, cơ sởthờtự, tín đồ\nTôn giáo mới là sựpha trộn của ác tôn giáo truyền thống, khi có sựchuyển biến kt, xã\nhội có sựvận động của đời sống sẽxuất hiện nhiều tôn giáo. Hiện tượng chuyển đổi tôn giáo\n\n\n**Cô ôn tập**\nChủnghĩa dân tộc và chủnghĩa dân tộc cực đoan, chủnghĩa ly khai dân tộc\n\n Chủnghĩa dân tộc cực đoan và chủnghĩa ly khai dân tộc là trào lưu gây ra sự\nchia rẽvà kì thịdân tộc, khoét sâu và cốtình khơi dậy sựbất hòa, kịch động\nlòng thù hận giữa các dân tộc, thổi phồng sựtựcao tựđại vềdân tộc mình\n\n Hậu quảnghiêm trọng là xung đột, nội chiến thểhiện dưới nhiều hình thức\nchiến tranh lớn, vừa và nhỏ, chiến t..."
|
| 76 |
+
}
|
| 77 |
+
],
|
| 78 |
+
"model_verdict": {
|
| 79 |
+
"supported": true,
|
| 80 |
+
"confidence": 0.99,
|
| 81 |
+
"evidence": "TÍnh chất chính trịcủa tôn giáo chỉ xuất hiện khi xã hội đã phân chia giai cấp, có sự khác biệt, sự đối kháng về lợi ích.",
|
| 82 |
+
"reason": "Câu trả lời trùng khớp với nội dung trong Context."
|
| 83 |
+
}
|
| 84 |
+
},
|
| 85 |
+
"2": {
|
| 86 |
+
"supported_by_embeddings": true,
|
| 87 |
+
"max_similarity": 0.7629456520080566,
|
| 88 |
+
"evidence": [
|
| 89 |
+
{
|
| 90 |
+
"idx": 34,
|
| 91 |
+
"page": 20,
|
| 92 |
+
"score": 0.7629456520080566,
|
| 93 |
+
"text": "Giai cấp thì có giai cấp công nhân và nông dân\nTầng lớp có tri thức, doanh nhân, thương,\nCơ cấu xã hội thời kì quá độ\n+Công nhân: vai trò nòng cốt trong liên minh, lực lượng đi đầu trong sựnghiệp\n\nCNH-HDH. +Nông dân: cơ sở, lực lương quan trọng phát triển kt-xã hội, giữvững ổn định chính\ntrị\n-Kinh tếcơ bản quy định nhất: xác định đúng cơ cấu\nQuan điểm nhất quán: phát triển nền kinh tếthành phần\n-Chính trị: giữvững lập trường chính trị- tư tưởng của giai cấp công nhân, vai trò\nlãnh đạo của Đảng cộng sản, xây dựng Đảng vững mạnh, xây dựng nhà nước pháp\nquyền vềXHCN của dân, do dân, vì dân\n-Văn hóa, xã hội: gắn tăng trưởng kinh tếvới phát triển văn hóa, phát triển, xây dựng\ncon người và thực hiện tiến bộ. Biến văn hóa trởthành tài sản của xã hội. Văn hóa, xã\nhội của liên minh giai cấp tầng lớp còn được thểhiện qua nâng cao chất lượng\nnguồn nhân lực, dân trí, xóa đói giảm nghèo, thực hiện an sinh xã hội\n\n\nPhương hướng tăng cường\n1. Đẩy mạnh quá trình CNH, HDH, giải quyết tốt mối quan hệgiữ..."
|
| 94 |
+
},
|
| 95 |
+
{
|
| 96 |
+
"idx": 1,
|
| 97 |
+
"page": 10,
|
| 98 |
+
"score": 0.5911743640899658,
|
| 99 |
+
"text": "##### **3.2. THỰC TRẠNG GCCN VIỆT NAM VÀ VẤN ĐỀĐẶT RA HIỆN NAY**\n\nNội dung SMLS hiện nay\nVỀNỘI DUNG KINH TẾ\n\n - Giai cấp công nhân là nguồn nhân lực chủyếu tham gia phát triển kinh tếthị\ntrường định hướng XHCN;\n\n - Lực lượng đi đầu trong sựnghiệp đẩy mạnh công nghiệp hóa, hiện đại hóa\n\nđất nước\n\n - Làm cho nước ta trởthành một nước công nghiệp theo hướng hiện đại, định\nhướng XHCN\nVỀNỘI DUNG CHÍNH TRỊ- XÃ HỘI\n\n - Giữvững và tăng cường sựlãnh đạo của Đảng,\n\n - Giữvững bản chất giai cấp công nhân của Đảng, giai cấp công nhân cùng với\nnhân dân lao động dưới sựlãnh đạo của Đảng cộng sản củng cốvà hoàn\nthiện hệthống chính trịXHCN\n\n - Xây dựng nhà nước của dân, do dân, vì dân, xây dựng nền dân chủXHCN, bảo\nvệchếđộxã hội chủnghĩa. VỀNỘI DUNG TƯ TƯỞNG – VĂN HÓA\n\n - Xây dựng và phát triển nền văn hóa Việt Nam tiên tiến, đậm đà bản sắc dân\ntộc, nội dung cốt lõi là xây dựng con người mới XHCN. - Bảo vệsựtrong sáng của chủnghĩa Mác – Lê nin và tư tưởng HồChí Minh,\nchống lại những quan điểm s..."
|
| 100 |
+
},
|
| 101 |
+
{
|
| 102 |
+
"idx": 22,
|
| 103 |
+
"page": 29,
|
| 104 |
+
"score": 0.5815836191177368,
|
| 105 |
+
"text": "Công nhân, nông dân, trí thức, thanh niên, doanh nhiên, phụnữ\n\n Phân tích dc vịtrí, vai trò từng giai cấp, tầng ớp\n\n Một câu tổng kết với từng vịtrí, vai trò, vì sao phải thực hiện liên minh các giai\ncấp\n\n\n5. **CHƯƠNG 6: VẤN ĐỀDÂN TỘC VÀ TÔN GIÁO**\n\n**TÔN GIÁO** : NẮM nguyên tắc giải quyết vấn đềTG trong thời kì quá độ, đặc điểm tôn\ngiáo ởVN, các chính sách của nhà nước và đảng vềtôn giáo\nLiên hệbản thân, ac nhận thức thếnào vềtôn giáo trong thời kì quá độxây dựng\n\nCNXH\n\n\nCHƯƠNG 7: GIA ĐINH\n\nNhững biến đổi của gia đình VN (3 biến đổi) - AC hãy nêu những biến đổi của gia\nđình VN trong thời kì quá độ, ac hãy nêu những phướng hướng, giái pháp đểxây\ndựng. Là sv, ac làm gì đểxây dựng\n\n\nDownloaded by Adoft Putin (dinhnhatthanh248@gmail.com)"
|
| 106 |
+
}
|
| 107 |
+
],
|
| 108 |
+
"model_verdict": {
|
| 109 |
+
"supported": false,
|
| 110 |
+
"confidence": 0.96,
|
| 111 |
+
"evidence": "Giai cấp thì có giai cấp công nhân và nông dân",
|
| 112 |
+
"reason": "Ngữ cảnh chỉ liệt kê giai cấp công nhân và nông dân là hai giai cấp riêng biệt, không nói rằng giai cấp công nhân bao gồm nông dân và thợ thủ công"
|
| 113 |
+
}
|
| 114 |
+
},
|
| 115 |
+
"3": {
|
| 116 |
+
"supported_by_embeddings": true,
|
| 117 |
+
"max_similarity": 0.5998344421386719,
|
| 118 |
+
"evidence": [
|
| 119 |
+
{
|
| 120 |
+
"idx": 28,
|
| 121 |
+
"page": 2,
|
| 122 |
+
"score": 0.5998344421386719,
|
| 123 |
+
"text": "=> đây là những con đường không tưởng, muốn đạt được phải qua đấu tranh và cách mạng,\nkhông vạch ra đc giai cấp nào là giai cấp mang sứmệnh lịch sử. **3. Chủnghĩa xã hội khoa học:**\nCũng hướng đến những tựdo, bình đẳng, bác ái,... nhưng đã vạch ra được giai cấp\nmang sứmệnh lịch sửlà giai cấp công nhân\n**Nghĩa rộng: Là CN Mác- Lê nin luận giải từcác góc độTH, KTCT và chính trị- xã**\n**hội vềsựchuyển biến tất yếu của XH loài người từCNTB lên CNXH.**\n**Nghĩa hẹp: là một trong ba bộphận hợp thành của CN Mác- Lenin (triết học, kinh**\n**tếCT và chủnghĩa xã hội khoa học).**\n\n\n**4. Chủnghĩa xã hội lí luận**\nBao gồm chủnghĩa xã hội không tưởng và chủnghĩa xã hội khoa hoc. **5. Chủnghĩa xã hội hiện thực**\nVận dụng các chủnghĩa xã hội vào xây dựng thực tiễn (CMT10 Nga - 1917)\n\n\nDownloaded by Adoft Putin (dinhnhatthanh248@gmail.com)"
|
| 124 |
+
},
|
| 125 |
+
{
|
| 126 |
+
"idx": 5,
|
| 127 |
+
"page": 5,
|
| 128 |
+
"score": 0.5852417945861816,
|
| 129 |
+
"text": "Con đường, cách thức và phương thức đấu tranh nhằm giải phóng con người, giải\nphóng xã hội khỏi tư hữu, áp bức, bóc lột, xây dựng một xã hội mới tiến bộ, công\nbằng, bình đẳng\n**2. Là một chếđộxã hội hiện thức, một mô hinh, một kiểu tổchức xã hội theo**\n**những nguyên tắc của CNXH**\n\n\n**3. Là một phong trào thực tiễn**\n\n### **1.2 Những điều kiện ra đời của CNXH khoa học**\n\n\n1.2.1. Điều kiện khách quan\n1.2.2. Điều kiện chủquan (vai trò của Mac Angghen\n\n### **2.2 VI."
|
| 130 |
+
},
|
| 131 |
+
{
|
| 132 |
+
"idx": 31,
|
| 133 |
+
"page": 3,
|
| 134 |
+
"score": 0.576014518737793,
|
| 135 |
+
"text": "Chủnghĩa xã hội vs Xã hội chủnghĩa\nChủnghĩa xã hội là một danh từ\nXã hội chủnghĩa là một tính từ\n\n\nThếlực thù địch\n+ Phủnhận: 1886 -> Đổi mới\n+ Cho rằng kinh tếthịtrường định hướng xã hội chủnghĩa không có thực\n=> Có thành tựu hay không có thành tựu đều bịcông kích\n\n\n**Vì sao nói chủnghĩa Mác Lênin vừa thống nhất vừa độc lập với nhau?**\n➢ Thống nhất vì nó là những luận điểm khoa học,\n➢ là hệtư tưởng của giai cấp công nhân\n➢ Đều hướng đến những giá trịtựdo,... mà con người đang hướng đến\n\n\nTriết học Mác Lenin: nghiên cứu những quy luật chung nhất của tựnhiên, xã hội, tư\nduy của 5 HTKT-XH\nKT-CT học Mác Lenin: nghiên cứu quy luật kinh tếtrong quá trình SXVC của HTKT-XH\nTBCN và quá độlên CNXH\nChủnghĩa xã hội khoa học: nghiên cứu những quy luật chính trị- xã hội của HTKT\ncộng sản chủnghĩa\n\n### **1.1 Quan niệm vềchủnghĩa xã hội**\n\n\nCNTB →Ra đời vào thời kì chiếm hữu nô lệ: khi xã hội bắt đầu phân chia giai cấp\n(tầng lớp quý tộc, địa chủ,.."
|
| 136 |
+
}
|
| 137 |
+
],
|
| 138 |
+
"model_verdict": {
|
| 139 |
+
"supported": false,
|
| 140 |
+
"confidence": 0.9,
|
| 141 |
+
"evidence": "Không có đề cập đến \"công nghiệp cơ khí\" trong nội dung cung cấp.",
|
| 142 |
+
"reason": "Context không chứa thông tin nào về sự phát triển của công nghiệp cơ khí là điều kiện kinh tế để chủ nghĩa xã hội ra đời."
|
| 143 |
+
}
|
| 144 |
+
},
|
| 145 |
+
"4": {
|
| 146 |
+
"supported_by_embeddings": true,
|
| 147 |
+
"max_similarity": 0.6957789659500122,
|
| 148 |
+
"evidence": [
|
| 149 |
+
{
|
| 150 |
+
"idx": 47,
|
| 151 |
+
"page": 18,
|
| 152 |
+
"score": 0.6957789659500122,
|
| 153 |
+
"text": "Phương diện tổchức và quản lí xã hội\n\n\nQuan điểm của Đảng cộng sản vềdân chủ(nền dân chủxã hội chủnghĩa)\n\n - QUyền lực thuộc vềnhân dân\n\n - Dân chủgắn liền với công bằng xã hội\n\n - Dân chủđi đôi với kỷluật, kỷcương\n\n - Dân chủtrên mọi lĩnh vực đời sống\n\n - Dân chủđược thểhiện bằng pháp luật\n\n\nNền dân chủchủnô và dân chủtư sản đều là quyền lực thuộc vềtay một giai cấp\nchứkhông phải tất cảcác giai cấp - không phải nền dân chủcho đa sốtrong xã hội\n(không có nền dân chủcho tất cảchỉcó cho đại đa số)\n\n\nĐặc điểm của nhà nước pháp quyền XHCN ởViệt Nam (6 nội dung phải nhớ)\n\n - Bản chất kinh tế\n\n - Bản chất chính trị\n\n - Bản chất xã hội - văn hóa\n\n\nPhải lí giải: vd nếu không có đảng thì có thểđảm bảo dân chủcho mọi tầng lớp\ntrong xã hội không\nQuan niệm chung vềnhà nước pháp quyền\n\n\nDownloaded by Adoft Putin (dinhnhatthanh248@gmail.com)"
|
| 154 |
+
},
|
| 155 |
+
{
|
| 156 |
+
"idx": 31,
|
| 157 |
+
"page": 3,
|
| 158 |
+
"score": 0.6646752953529358,
|
| 159 |
+
"text": "Chủnghĩa xã hội vs Xã hội chủnghĩa\nChủnghĩa xã hội là một danh từ\nXã hội chủnghĩa là một tính từ\n\n\nThếlực thù địch\n+ Phủnhận: 1886 -> Đổi mới\n+ Cho rằng kinh tếthịtrường định hướng xã hội chủnghĩa không có thực\n=> Có thành tựu hay không có thành tựu đều bịcông kích\n\n\n**Vì sao nói chủnghĩa Mác Lênin vừa thống nhất vừa độc lập với nhau?**\n➢ Thống nhất vì nó là những luận điểm khoa học,\n➢ là hệtư tưởng của giai cấp công nhân\n➢ Đều hướng đến những giá trịtựdo,... mà con người đang hướng đến\n\n\nTriết học Mác Lenin: nghiên cứu những quy luật chung nhất của tựnhiên, xã hội, tư\nduy của 5 HTKT-XH\nKT-CT học Mác Lenin: nghiên cứu quy luật kinh tếtrong quá trình SXVC của HTKT-XH\nTBCN và quá độlên CNXH\nChủnghĩa xã hội khoa học: nghiên cứu những quy luật chính trị- xã hội của HTKT\ncộng sản chủnghĩa\n\n### **1.1 Quan niệm vềchủnghĩa xã hội**\n\n\nCNTB →Ra đời vào thời kì chiếm hữu nô lệ: khi xã hội bắt đầu phân chia giai cấp\n(tầng lớp quý tộc, địa chủ,.."
|
| 160 |
+
},
|
| 161 |
+
{
|
| 162 |
+
"idx": 10,
|
| 163 |
+
"page": 13,
|
| 164 |
+
"score": 0.6248639822006226,
|
| 165 |
+
"text": "- Mâu thuẫn giữa LLSX và QHSX, mâu thuẫn tư sản và vô sản\n\n\nĐiều kiện chính trị\n\n\n - GCCN phát triển cảvềsốlượng và chất lượng\n\n\n - GCCN phải giác ngộcách mạng và tốchức ra chính Đảng của mình\n\n\n - GCCN phải kiên quyết giành chính quyền từtay GCTS khi có thời cơ cách\n\n\nmạng và muốn giành chính quyền phải thông qua cách mạng vô sản\n\n\n=> Áp lực của phong trào đấu tranh GCCN, áp lực từsựra đời icủa CNXH\n\n##### **1.3 Những đặc trưng bản chất của chủnghĩa xã hội theo quan điểm** **của Mác**\n\n\n1. Giai phóng GC, giải phóng DT, giải phóng XH, giải phóng con người (giải\nphóng toàn bộcác tầng lớp bịáp bức bóc lột khác)\n**2. Là chếđộdo NDLĐ làm chủ(mọi chính sách đều phục vụnhân dân)**\n3. Có nền KT phát triển cao\n4. Có nhà nước kiểu mới mang bản chất GCCN (chương 5)\n5. Có nền văn hóa phát triển cao\n6. Đẩm bảo bình đăng, đoàn kết giữa các dân tộc (VN là nc đa dân tộc, đa văn\nhóa nên xây dựng đn sẽkhó khăn hơn), quan hệhợp tác hữu nghị\n\n### **2."
|
| 166 |
+
}
|
| 167 |
+
],
|
| 168 |
+
"model_verdict": {
|
| 169 |
+
"supported": true,
|
| 170 |
+
"confidence": 0.98,
|
| 171 |
+
"evidence": "1. Giai phóng GC... 2. Là chế độ... 3. Có nền KT phát triển cao 4. Có nhà nước kiểu mới mang bản chất GCCN 5. Có nền văn hóa phát triển cao 6. Đảm bảo bình đẳng, đoàn kết... (không có mục \"có hệ thống chính trị đa đảng\")",
|
| 172 |
+
"reason": "Trong danh sách 6 đặc trưng của chủ nghĩa xã hội theo Mác, không có mục nào đề cập đến hệ thống chính trị đa đảng, nên đáp án \"Có hệ thống chính trị đa đảng\" là đúng."
|
| 173 |
+
}
|
| 174 |
+
},
|
| 175 |
+
"5": {
|
| 176 |
+
"supported_by_embeddings": true,
|
| 177 |
+
"max_similarity": 0.5826756358146667,
|
| 178 |
+
"evidence": [
|
| 179 |
+
{
|
| 180 |
+
"idx": 3,
|
| 181 |
+
"page": 3,
|
| 182 |
+
"score": 0.5826756358146667,
|
| 183 |
+
"text": "nắm giữtài sản, nô lệlà công cụlao động)\nCNXH không tưởng (trước 1848, trước Mác- Ăngghen)\n**a) Tư tưởng xã hội chủnghĩa trước Mác**\n❖ Tư tưởng XHCN thời cổđại: Phương Đông (địa chủ- phong kiến), phương Tây\n(chủnô, tang lữ- nô lệ) => thểhiện bằng các cuộc đấu tranh của quần chúng\nnhân dân lao động đòi lại quyền dân chủtuy nhiên còn rời rạc (VD khởi nghĩa\nSpartacus). ❖ Tư tưởng XHCN thời trung đại: Phương Tây (đêm trường trung cổ, giáo hội có\nquyền lực hơn cảnhà nước). => thểhiện bằng những câu chuyện, văn thở\nphản ánh ước mơ về“thời đại hoàng kim”\n❖ Tư tưởng XHCN thời cận đại (đầu TK16 - đầu TK19): xuất hiện tầng lớp công\nnhân => tư tưởng CNXH bắt đầu được thành lập. Thểkỷ16 - Thomas More với\ntác phẩm Utopia) - thuật ngữ“Cừu ăn thịt người”. Grachus Babeuf - tuyên\nngôn của những người binh dân\n❖ Thếkỉ19: Tư tưởng XHCN thểhiện dạng học thuyết phê phán: 3 đại diện tiêu\nbiểu (Saint Simon, Charles Fourier, Robert Owen): bước sang giai đoạn mới\n\n\nDownloaded by Adoft Putin (dinhnhatthanh248@g..."
|
| 184 |
+
},
|
| 185 |
+
{
|
| 186 |
+
"idx": 40,
|
| 187 |
+
"page": 5,
|
| 188 |
+
"score": 0.5630186796188354,
|
| 189 |
+
"text": "Lenin bảo vệ, vận dụng và phát triển sáng tạo** **CNXHKH**\n\n\n2.2.2 Thời kì sau CM tháng 10 Nga:\nVềchính trị: vấn đềdân chủvà chuyên chính vô sản\nVềkinh tế: vận hành theo thịtrường, kinh tếNep\n\n##### **_Đối diện: Nhận diện cách mạng màu - Việt Nam có phải đối diện_** **_nguy cơ xảy ra cách mạng màu hay không?_**\n\n+ Biểu hiện của cách mạng màu: các cuộc lật độchếđộhiện tại bằng phương\nthức truyền bá, kích động, lôi kéo người dân tham gia vào các cuộc biểu tình\nkhiến cho các hoạt động xã hội bịngưng trệkhiến cho xung đột người dân và\nchính quyền ngày càng lớn\n+ Bắt nguồn từcáo buộc gian lận bầu cử, nạn tham nhũng, mâu thuẫn lợi ích,\nmâu thuẫn sắc tộc, khó khăn kinh tế… => bịkích động trởthành cách mạng\nhoa nhài, cách mạng hoa tulip,... + Hậu quả: đồng tiền mất giá, cuộc sống đình trệ, kinh tếrơi vào khủng hoảng\ntrầm trọng, đất nước trởthành vùng đệm quốc tế, người dân phải tịnạn, gặp\n\nkhó khăn\n\n+ VN có phải đối mặt với cách mạng màu không? Mục tiêu tấn công nhằm xóa\nbỏCNXH -> VN cũng nằm ..."
|
| 190 |
+
},
|
| 191 |
+
{
|
| 192 |
+
"idx": 28,
|
| 193 |
+
"page": 2,
|
| 194 |
+
"score": 0.5546197891235352,
|
| 195 |
+
"text": "=> đây là những con đường không tưởng, muốn đạt được phải qua đấu tranh và cách mạng,\nkhông vạch ra đc giai cấp nào là giai cấp mang sứmệnh lịch sử. **3. Chủnghĩa xã hội khoa học:**\nCũng hướng đến những tựdo, bình đẳng, bác ái,... nhưng đã vạch ra được giai cấp\nmang sứmệnh lịch sửlà giai cấp công nhân\n**Nghĩa rộng: Là CN Mác- Lê nin luận giải từcác góc độTH, KTCT và chính trị- xã**\n**hội vềsựchuyển biến tất yếu của XH loài người từCNTB lên CNXH.**\n**Nghĩa hẹp: là một trong ba bộphận hợp thành của CN Mác- Lenin (triết học, kinh**\n**tếCT và chủnghĩa xã hội khoa học).**\n\n\n**4. Chủnghĩa xã hội lí luận**\nBao gồm chủnghĩa xã hội không tưởng và chủnghĩa xã hội khoa hoc. **5. Chủnghĩa xã hội hiện thực**\nVận dụng các chủnghĩa xã hội vào xây dựng thực tiễn (CMT10 Nga - 1917)\n\n\nDownloaded by Adoft Putin (dinhnhatthanh248@gmail.com)"
|
| 196 |
+
}
|
| 197 |
+
],
|
| 198 |
+
"model_verdict": {
|
| 199 |
+
"supported": false,
|
| 200 |
+
"confidence": 0.85,
|
| 201 |
+
"evidence": "Context chỉ đề cập đến giai cấp công nhân là giai cấp mang sứ mệnh lịch sử, nhưng không nêu rõ sứ mệnh lịch sử của Cách mạng xã hội chủ nghĩa là \"những nhiệm vụ quan trọng, thiêng liêng...\"",
|
| 202 |
+
"reason": "Không có bằng chứng trong nội dung cung cấp xác nhận định nghĩa cụ thể của sứ mệnh lịch sử như trong đáp án"
|
| 203 |
+
}
|
| 204 |
+
}
|
| 205 |
+
}
|
| 206 |
+
}
|
test/raw_resp.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"id": "chatcmpl-84e4f53d-9bca-4dd8-89d3-7a4a9b69b860",
|
| 3 |
+
"choices": [
|
| 4 |
+
{
|
| 5 |
+
"finish_reason": "stop",
|
| 6 |
+
"index": 0,
|
| 7 |
+
"message": {
|
| 8 |
+
"content": "{\n \"supported\": true,\n \"confidence\": 0.99,\n \"evidence\": \"BERT-base có 12 lớp encoder ... Mỗi lớp có 12 head ... mỗi token có vector 768 chiều\",\n \"reason\": \"Context xác nhận BERT-base có 12 lớp encoder, hidden size 768 và 12 attention head, nên đáp án a được chứng thực.\"\n}",
|
| 9 |
+
"reasoning": "We need to determine if the answer (option a) is supported by the context. The context includes: \"Cấu trúc BERT-base có 12 lớp encoder, mỗi lớp bao gồm: ... Mỗi lớp có 12 head, ... d_k: 768/12=64. ...\". Also earlier: \"BERT-base có 12 lớp encoder\". It mentions hidden size 768. So option a: \"BERT có 12 lớp encoder, mỗi lớp có kích thước ẩn là 768 và 12 attention head.\" This matches. So supported true. Provide confidence maybe 0.99. Evidence: \"BERT-base có 12 lớp encoder\" and \"Mỗi lớp có 12 head\" and hidden size 768 mentioned in description of token vector dimension. Provide short citation. Provide reason.",
|
| 10 |
+
"role": "assistant"
|
| 11 |
+
}
|
| 12 |
+
}
|
| 13 |
+
],
|
| 14 |
+
"created": 1755749149,
|
| 15 |
+
"model": "gpt-oss-120b",
|
| 16 |
+
"system_fingerprint": "fp_e25f231b468af246abb0",
|
| 17 |
+
"object": "chat.completion",
|
| 18 |
+
"usage": {
|
| 19 |
+
"prompt_tokens": 1714,
|
| 20 |
+
"completion_tokens": 265,
|
| 21 |
+
"total_tokens": 1979,
|
| 22 |
+
"prompt_tokens_details": {
|
| 23 |
+
"cached_tokens": 0
|
| 24 |
+
}
|
| 25 |
+
},
|
| 26 |
+
"time_info": {
|
| 27 |
+
"queue_time": 0.000124009,
|
| 28 |
+
"prompt_time": 0.063482573,
|
| 29 |
+
"completion_time": 0.18115486,
|
| 30 |
+
"total_time": 0.2471165657043457,
|
| 31 |
+
"created": 1755749149
|
| 32 |
+
}
|
| 33 |
+
}
|
test/test-api-key.py
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
from qdrant_client import QdrantClient
|
| 3 |
+
|
| 4 |
+
qdrant_client = QdrantClient(
|
| 5 |
+
url=os.environ.get('QDRANT_URL'),
|
| 6 |
+
api_key=os.environ.get('QDRANT_API_KEY'),
|
| 7 |
+
)
|
| 8 |
+
print(qdrant_client.get_collections())
|
| 9 |
+
|
| 10 |
+
# qdrant_client.recreate_collection(
|
| 11 |
+
# collection_name="programming",
|
| 12 |
+
# vectors_config={
|
| 13 |
+
# "my_vector_name": models.VectorParams(size=1536, distance=models.Distance.COSINE),
|
| 14 |
+
# },
|
| 15 |
+
# )
|
| 16 |
+
print()
|
| 17 |
+
print(os.environ.get('HF_API_KEY'))
|
| 18 |
+
print(os.environ.get('TOGETHER_API_KEY'))
|
| 19 |
+
print(os.environ.get('QDRANT_URL'))
|
| 20 |
+
print(os.environ.get('QDRANT_API_KEY'))
|
| 21 |
+
print(os.environ.get('CEREBRAS_API_KEY'))
|
| 22 |
+
# cerebras API: your_key
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
"""
|
| 26 |
+
Debugging FastAPI:
|
| 27 |
+
uvicorn app.py:app --reload
|
| 28 |
+
|
| 29 |
+
MacOS:
|
| 30 |
+
export TOGETHER_API_KEY="YOUR_API_KEY"
|
| 31 |
+
|
| 32 |
+
Windows:
|
| 33 |
+
$env:CEREBRAS_API_KEY = "your_key"
|
| 34 |
+
$env:QDRANT_URL = "your_url"
|
| 35 |
+
$env:QDRANT_API_KEY = "your_key"
|
| 36 |
+
"""
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
"""Token Count Test
|
| 40 |
+
INPUT_token_count:10616
|
| 41 |
+
OUTPUT_token_count:4808
|
| 42 |
+
AVG_INPUT_token_count:1061.6
|
| 43 |
+
AVG_OUTPUT_token_count:480.8
|
| 44 |
+
TOTAL_TOKEN_COUNT:[1717 1743 1417 1419 1483 1630 1516 1619 1580 1300]
|
| 45 |
+
TOKEN_COUNT_PER_GENERATION - :[15424.]
|
| 46 |
+
AVG_TOKEN_COUNT_PER_GENERATION:[np.float64(15424.0), 1]
|
| 47 |
+
|
| 48 |
+
INPUT_token_count:10299.0
|
| 49 |
+
OUTPUT_token_count:5628.0
|
| 50 |
+
AVG_INPUT_token_count:1029.9
|
| 51 |
+
AVG_OUTPUT_token_count:562.8
|
| 52 |
+
TOTAL_TOKEN_COUNT:[1852. 1520. 1615. 1790. 1539. 1562. 1290. 1686. 1460. 1613.]
|
| 53 |
+
TOKEN_COUNT_PER_GENERATION - :[15424. 15927.]
|
| 54 |
+
AVG_TOKEN_COUNT_PER_GENERATION:[np.float64(15675.5), 2]
|
| 55 |
+
|
| 56 |
+
INPUT_token_count:9640.0
|
| 57 |
+
OUTPUT_token_count:5576.0
|
| 58 |
+
AVG_INPUT_token_count:964.0
|
| 59 |
+
AVG_OUTPUT_token_count:557.6
|
| 60 |
+
TOTAL_TOKEN_COUNT:[1252. 1835. 1490. 1537. 1394. 1620. 1670. 1707. 1458. 1253.]
|
| 61 |
+
TOKEN_COUNT_PER_GENERATION - :[15424. 15927. 15216.]
|
| 62 |
+
AVG_TOKEN_COUNT_PER_GENERATION:[np.float64(15522.333333333334), 3]
|
| 63 |
+
|
| 64 |
+
INPUT_token_count:9356.0
|
| 65 |
+
OUTPUT_token_count:5277.0
|
| 66 |
+
AVG_INPUT_token_count:935.6
|
| 67 |
+
AVG_OUTPUT_token_count:527.7
|
| 68 |
+
TOTAL_TOKEN_COUNT:[1368. 1295. 1849. 1523. 1468. 1473. 1486. 1426. 1595. 1150.]
|
| 69 |
+
TOKEN_COUNT_PER_GENERATION - :[15424. 15927. 15216. 14633.]
|
| 70 |
+
AVG_TOKEN_COUNT_PER_GENERATION:[np.float64(15300.0), 4]
|
| 71 |
+
|
| 72 |
+
INPUT_token_count:9828.0
|
| 73 |
+
OUTPUT_token_count:4758.0
|
| 74 |
+
AVG_INPUT_token_count:982.8
|
| 75 |
+
AVG_OUTPUT_token_count:475.8
|
| 76 |
+
TOTAL_TOKEN_COUNT:[1820. 1235. 1911. 1591. 1312. 1242. 1372. 1533. 1393. 1177.]
|
| 77 |
+
TOKEN_COUNT_PER_GENERATION - :[15424. 15927. 15216. 14633. 14586.]
|
| 78 |
+
AVG_TOKEN_COUNT_PER_GENERATION:[np.float64(15157.2), 5]
|
| 79 |
+
"""
|
test/text_chunks.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
['# **Các thuật toán sắp xếp (p2)** **(sorting algorithms)**\n\n**Nguyễn Mạnh Hiển**\nKhoa Công nghệ thông tin\n[hiennm@tlu.edu.vn](mailto:hiennm@wru.vn)', '## **Các thuật toán sắp xếp - phần 2**\n\n\nSắp xếp vun đống (heap sort)\n\nSắp xếp trộn (merge sort)\n\nSắp xếp nhanh (quick sort)', '## **Sắp xếp vun đống (heap sort)**\n\n\nĐống nhỏ nhất (min-heap)\n\n\n−\nXây dựng đống: O(N)\n\n−\nThực hiện N phép deleteMin để lấy ra phần tử nhỏ\n\nnhất: O(N log N)\n\n−\nĐộ phức tạp tổng thể: O(N log N)\n\n−\nYêu cầu thêm một mảng nữa để lưu trữ các kết quả\n\nĐống lớn nhất (max-heap):\n\n\n−\nLưu trữ các phần tử bị xóa ở cuối vector đống', '### **Ví dụ với đống lớn nhất (max-heap)**\n\nSau buildHeap() Sau deleteMax() đầu tiên', '#### **Cài đặt sắp xếp vun đống**', '## **Sắp xếp trộn (merge sort)**\n\n\nBan đầu có N phần tử chưa sắp xếp\n\nChia N phần tử thành hai nửa\n\nSắp xếp đệ quy mỗi nửa dùng mergeSort\n\n\n−\nTrường hợp cơ sở: N = 1 (không cần sắp xếp)\n\nTrộn (merge) hai nửa (đã được sắp xếp)', '## **Ví dụ về trộn (merge)**\n\n1 15 24 26 2 13 27 38\n\n|1|15|24|26|\n|---|---|---|---|\n|||||\n\n\n|2|13|27|38|\n|---|---|---|---|\n|||||\n\n\n\n1 15 24 26 2 13 27 38 1\n\n|1|15|24|26|\n|---|---|---|---|\n|||||\n\n\n|2|13|27|38|\n|---|---|---|---|\n|||||\n\n\n|1|Col2|Col3|Col4|Col5|Col6|Col7|Col8|\n|---|---|---|---|---|---|---|---|\n|||||||||\n\n\n\n1 15 24 26 2 13 27 38 1 2\n\n|1|15|24|26|\n|---|---|---|---|\n|||||\n\n\n|2|13|27|38|\n|---|---|---|---|\n|||||\n\n\n|1|2|Col3|Col4|Col5|Col6|Col7|Col8|\n|---|---|---|---|---|---|---|---|\n|||||||||\n\n\n\n1 15 24 26 2 13 27 38 1 2 13\n\n\n\n|1|15|24|26|\n|---|---|---|---|\n|||||\n\nCó N bước\n\n\n|2|13|27|38|\n|---|---|---|---|\n|||||\n\n\n|1|2|13|Col4|Col5|Col6|Col7|Col8|\n|---|---|---|---|---|---|---|---|\n|||||||||\n\nMỗi bước có thể có một phép so sánh và có một phần tử được\n\nchèn vào mảng thứ ba \uf0e0 mỗi bước mất thời gian hằng\n\n\uf0e0 Tổng thời gian là O(N)', '### **Ví dụ về sắp xếp trộn (merge sort)**\n\n1 24 26 15 13 2 27 38\n\n\n1 24 26 15 13 2 27 38\n\n\n1 24 26 15 13 2 27 38\n\n\n1 24 26 15 13 2 27 38\n\n\n1 24 15 26 2 13 27 38\n\n\n1 15 24 26 2 13 27 38\n\n\n1 2 13 15 24 26 27 38', '#### **Cài đặt sắp xếp trộn**']
|
utils.py
CHANGED
|
@@ -3,19 +3,37 @@ import json
|
|
| 3 |
from typing import Dict, Any
|
| 4 |
import requests
|
| 5 |
import os
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
|
|
|
|
| 7 |
API_URL = "https://api.cerebras.ai/v1/chat/completions"
|
| 8 |
-
# HF_KEY = os.environ['HF_API_KEY']
|
| 9 |
CEREBRAS_API_KEY = os.environ['CEREBRAS_API_KEY']
|
|
|
|
| 10 |
HEADERS = {"Authorization": f"Bearer {CEREBRAS_API_KEY}", "Content-Type": "application/json"}
|
| 11 |
JSON_OBJ_RE = re.compile(r"(\{[\s\S]*\})", re.MULTILINE)
|
| 12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
def _post_chat(messages: list, model: str, temperature: float = 0.2, timeout: int = 60) -> str:
|
| 14 |
payload = {"model": model, "messages": messages, "temperature": temperature}
|
| 15 |
resp = requests.post(API_URL, headers=HEADERS, json=payload, timeout=timeout)
|
| 16 |
resp.raise_for_status()
|
| 17 |
data = resp.json()
|
| 18 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
# handle various shapes
|
| 20 |
if "choices" in data and len(data["choices"]) > 0:
|
| 21 |
# prefer message.content
|
|
@@ -23,13 +41,15 @@ def _post_chat(messages: list, model: str, temperature: float = 0.2, timeout: in
|
|
| 23 |
|
| 24 |
if isinstance(ch, dict) and "message" in ch and "content" in ch["message"]:
|
| 25 |
return ch["message"]["content"]
|
| 26 |
-
|
| 27 |
if "text" in ch:
|
| 28 |
return ch["text"]
|
| 29 |
-
|
|
|
|
| 30 |
# final fallback
|
| 31 |
raise RuntimeError("Unexpected HF response shape: " + json.dumps(data)[:200])
|
| 32 |
|
|
|
|
| 33 |
def _safe_extract_json(text: str) -> dict:
|
| 34 |
# remove triple backticks
|
| 35 |
text = re.sub(r"```(?:json)?\n?", "", text)
|
|
@@ -46,6 +66,7 @@ def _safe_extract_json(text: str) -> dict:
|
|
| 46 |
fixed = re.sub(r",\s*([}\]])", r"\1", js)
|
| 47 |
return json.loads(fixed)
|
| 48 |
|
|
|
|
| 49 |
def generate_mcqs_from_text(
|
| 50 |
source_text: str,
|
| 51 |
n: int = 3,
|
|
@@ -85,3 +106,126 @@ def generate_mcqs_from_text(
|
|
| 85 |
if not isinstance(parsed, dict) or len(parsed) != n:
|
| 86 |
raise ValueError(f"Generator returned invalid structure. Raw:\n{raw}")
|
| 87 |
return parsed
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
from typing import Dict, Any
|
| 4 |
import requests
|
| 5 |
import os
|
| 6 |
+
import numpy as np
|
| 7 |
+
import uuid
|
| 8 |
+
import datetime
|
| 9 |
+
import pathlib
|
| 10 |
|
| 11 |
+
#TODO: allow to choose different provider later + dynamic routing when token expired
|
| 12 |
API_URL = "https://api.cerebras.ai/v1/chat/completions"
|
|
|
|
| 13 |
CEREBRAS_API_KEY = os.environ['CEREBRAS_API_KEY']
|
| 14 |
+
|
| 15 |
HEADERS = {"Authorization": f"Bearer {CEREBRAS_API_KEY}", "Content-Type": "application/json"}
|
| 16 |
JSON_OBJ_RE = re.compile(r"(\{[\s\S]*\})", re.MULTILINE)
|
| 17 |
|
| 18 |
+
INPUT_TOKEN_COUNT = np.array([], dtype=int)
|
| 19 |
+
OUTPUT_TOKEN_COUNT = np.array([], dtype=int)
|
| 20 |
+
TOTAL_TOKEN_COUNT = np.array([], dtype=int)
|
| 21 |
+
TOTAL_TOKEN_COUNT_EACH_GENERATION = np.array([])
|
| 22 |
+
TIME_INFOs = {}
|
| 23 |
+
|
| 24 |
+
|
| 25 |
def _post_chat(messages: list, model: str, temperature: float = 0.2, timeout: int = 60) -> str:
|
| 26 |
payload = {"model": model, "messages": messages, "temperature": temperature}
|
| 27 |
resp = requests.post(API_URL, headers=HEADERS, json=payload, timeout=timeout)
|
| 28 |
resp.raise_for_status()
|
| 29 |
data = resp.json()
|
| 30 |
|
| 31 |
+
save_to_local('test/raw_resp.json', content=data)
|
| 32 |
+
|
| 33 |
+
#? Must update within _post_chat because it the original function for LLM generation
|
| 34 |
+
update_token_count(token_usage=data['usage']) # get data['usages']['prompt_tokens'] & data['usages']['completion_tokens']
|
| 35 |
+
update_time_info(time_info=data['time_info'])
|
| 36 |
+
|
| 37 |
# handle various shapes
|
| 38 |
if "choices" in data and len(data["choices"]) > 0:
|
| 39 |
# prefer message.content
|
|
|
|
| 41 |
|
| 42 |
if isinstance(ch, dict) and "message" in ch and "content" in ch["message"]:
|
| 43 |
return ch["message"]["content"]
|
| 44 |
+
|
| 45 |
if "text" in ch:
|
| 46 |
return ch["text"]
|
| 47 |
+
|
| 48 |
+
print(f'Generation Time: {data["time_info"]}')
|
| 49 |
# final fallback
|
| 50 |
raise RuntimeError("Unexpected HF response shape: " + json.dumps(data)[:200])
|
| 51 |
|
| 52 |
+
|
| 53 |
def _safe_extract_json(text: str) -> dict:
|
| 54 |
# remove triple backticks
|
| 55 |
text = re.sub(r"```(?:json)?\n?", "", text)
|
|
|
|
| 66 |
fixed = re.sub(r",\s*([}\]])", r"\1", js)
|
| 67 |
return json.loads(fixed)
|
| 68 |
|
| 69 |
+
|
| 70 |
def generate_mcqs_from_text(
|
| 71 |
source_text: str,
|
| 72 |
n: int = 3,
|
|
|
|
| 106 |
if not isinstance(parsed, dict) or len(parsed) != n:
|
| 107 |
raise ValueError(f"Generator returned invalid structure. Raw:\n{raw}")
|
| 108 |
return parsed
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
# helpers to read/reset token counts
|
| 112 |
+
def get_token_count_record():
|
| 113 |
+
global TOTAL_TOKEN_COUNT_EACH_GENERATION
|
| 114 |
+
TOTAL_TOKEN_COUNT_EACH_GENERATION = np.append(TOTAL_TOKEN_COUNT_EACH_GENERATION, np.sum(TOTAL_TOKEN_COUNT))
|
| 115 |
+
|
| 116 |
+
token_record = {
|
| 117 |
+
'INPUT_token_count': np.sum(INPUT_TOKEN_COUNT),
|
| 118 |
+
'OUTPUT_token_count': np.sum(OUTPUT_TOKEN_COUNT),
|
| 119 |
+
'AVG_INPUT_token_count': np.average(INPUT_TOKEN_COUNT),
|
| 120 |
+
'AVG_OUTPUT_token_count': np.average(OUTPUT_TOKEN_COUNT),
|
| 121 |
+
'TOTAL_token_count': TOTAL_TOKEN_COUNT,
|
| 122 |
+
'TOTAL_token_count_PER_GENERATION - ': TOTAL_TOKEN_COUNT_EACH_GENERATION,
|
| 123 |
+
'AVG_TOTAL_token_count_PER_GENERATION': [np.average(TOTAL_TOKEN_COUNT_EACH_GENERATION), len(TOTAL_TOKEN_COUNT_EACH_GENERATION)],
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
return token_record
|
| 127 |
+
|
| 128 |
+
|
| 129 |
+
def reset_token_count(reset_all=None):
|
| 130 |
+
"""Call in app.py. For Reset Token Count after 1 Generation Session"""
|
| 131 |
+
global INPUT_TOKEN_COUNT, OUTPUT_TOKEN_COUNT, TOTAL_TOKEN_COUNT, TOTAL_TOKEN_COUNT_EACH_GENERATION
|
| 132 |
+
|
| 133 |
+
INPUT_TOKEN_COUNT = np.array([])
|
| 134 |
+
OUTPUT_TOKEN_COUNT = np.array([])
|
| 135 |
+
TOTAL_TOKEN_COUNT = np.array([])
|
| 136 |
+
|
| 137 |
+
if reset_all:
|
| 138 |
+
TOTAL_TOKEN_COUNT_EACH_GENERATION = np.array([])
|
| 139 |
+
|
| 140 |
+
|
| 141 |
+
def update_token_count(token_usage):
|
| 142 |
+
"""Update Token Count for each generation
|
| 143 |
+
"usage": {
|
| 144 |
+
"prompt_tokens": 1209,
|
| 145 |
+
"completion_tokens": 313,
|
| 146 |
+
"total_tokens": 1522,
|
| 147 |
+
"prompt_tokens_details": {
|
| 148 |
+
"cached_tokens": 0
|
| 149 |
+
}
|
| 150 |
+
"""
|
| 151 |
+
global INPUT_TOKEN_COUNT, OUTPUT_TOKEN_COUNT, TOTAL_TOKEN_COUNT # get value from global
|
| 152 |
+
prompt_tokens = token_usage['prompt_tokens'] # INPUT token
|
| 153 |
+
completion_tokens = token_usage['completion_tokens'] # OUTPUT token
|
| 154 |
+
total_tokens = token_usage['total_tokens'] # TOTAL token
|
| 155 |
+
|
| 156 |
+
INPUT_TOKEN_COUNT = np.append(INPUT_TOKEN_COUNT, prompt_tokens)
|
| 157 |
+
OUTPUT_TOKEN_COUNT = np.append(OUTPUT_TOKEN_COUNT, completion_tokens)
|
| 158 |
+
TOTAL_TOKEN_COUNT = np.append(TOTAL_TOKEN_COUNT, total_tokens)
|
| 159 |
+
|
| 160 |
+
# print("Input Token Increase:", INPUT_TOKEN_COUNT)
|
| 161 |
+
# print("Output Token Increase:", OUTPUT_TOKEN_COUNT)
|
| 162 |
+
|
| 163 |
+
|
| 164 |
+
def save_logs(record: dict, log_path:str = "logs/generation_log.jsonl"):
|
| 165 |
+
"""
|
| 166 |
+
Append log to log_path
|
| 167 |
+
record: dict with keys you want to store (e.g. filename, input/output token_count, collection, etc..)
|
| 168 |
+
"""
|
| 169 |
+
# create file if not exist
|
| 170 |
+
p = pathlib.Path(log_path)
|
| 171 |
+
p.parent.mkdir(parents=True, exist_ok=True)
|
| 172 |
+
|
| 173 |
+
# add id/timestampt if missing
|
| 174 |
+
record.setdefault('id', str(uuid.uuid4()))
|
| 175 |
+
record.setdefault('timestamp_utc', datetime.datetime.now(datetime.timezone.utc).isoformat() + "Z") # get current time at timezone
|
| 176 |
+
|
| 177 |
+
# append as 1 json file for each generation
|
| 178 |
+
with open(p, "a", encoding='utf-8') as f:
|
| 179 |
+
f.write(json.dumps(record, ensure_ascii=False) + "\n")
|
| 180 |
+
|
| 181 |
+
|
| 182 |
+
def update_time_info(time_info):
|
| 183 |
+
"""
|
| 184 |
+
"time_info": {
|
| 185 |
+
"queue_time": 0.000600429,
|
| 186 |
+
"prompt_time": 0.052739054,
|
| 187 |
+
"completion_time": 0.15692187,
|
| 188 |
+
"total_time": 0.2117476463317871,
|
| 189 |
+
"created": 1755599458
|
| 190 |
+
}
|
| 191 |
+
"""
|
| 192 |
+
time_info['created'] = time_info
|
| 193 |
+
time_info['created'].pop('created')
|
| 194 |
+
|
| 195 |
+
|
| 196 |
+
def get_time_info():
|
| 197 |
+
global TIME_INFOs
|
| 198 |
+
return TIME_INFOs
|
| 199 |
+
# token_record = {
|
| 200 |
+
# 'completion_time': np.sum(INPUT_TOKEN_COUNT),
|
| 201 |
+
# 'total_time': np.sum(OUTPUT_TOKEN_COUNT),
|
| 202 |
+
# }
|
| 203 |
+
|
| 204 |
+
def log_pipeline(path, content):
|
| 205 |
+
print("Save result to test/mcq_output.json")
|
| 206 |
+
save_to_local(path=path, content=content)
|
| 207 |
+
token_record = get_token_count_record()
|
| 208 |
+
|
| 209 |
+
print("Token Record:")
|
| 210 |
+
for record, value in token_record.items():
|
| 211 |
+
print(f'{record}:{value}', '\n')
|
| 212 |
+
|
| 213 |
+
reset_token_count()
|
| 214 |
+
|
| 215 |
+
def save_to_local(path, content):
|
| 216 |
+
"""
|
| 217 |
+
path = 'test/raw_data.json'
|
| 218 |
+
path = 'test/mcq_output.json'
|
| 219 |
+
path = 'test/extract_output.md'
|
| 220 |
+
|
| 221 |
+
"""
|
| 222 |
+
p = pathlib.Path(path)
|
| 223 |
+
p.parent.mkdir(parents=True, exist_ok=True) # create folder if missing
|
| 224 |
+
p.touch(exist_ok=True) # create file if missing
|
| 225 |
+
|
| 226 |
+
if path.lower().endswith('.json'):
|
| 227 |
+
with open(path, 'w', encoding='utf-8') as f:
|
| 228 |
+
f.write(json.dumps(content, ensure_ascii=False, indent=2))
|
| 229 |
+
else:
|
| 230 |
+
with open(path, 'w', encoding='utf-8') as f:
|
| 231 |
+
f.write(f'{content}') # md, txt
|