fix preprocess and add train jina

This commit is contained in:
saeedfirouzi 2025-11-09 13:44:28 +00:00
parent 9ed840c333
commit 318c183d48
15 changed files with 575 additions and 53 deletions

5
.gitignore vendored
View File

@ -3,4 +3,7 @@ data
*/__pycache__/*
.env
.venv
*.json
*.json
models
*.log
research_notebook/data

View File

@ -1,12 +1,13 @@
import random
from tqdm import tqdm
import numpy as np
import faiss
from data_preprocess.text_embedder import TextEmbedder
THRESHOLD_MULTIPLY = 0.9
RANDOM_NEGATIVE_COUNT = 25
THRESHOLD_MULTIPLY = 0.95
RANDOM_NEGATIVE_COUNT = 6
batch_size = 100
text_embedder = TextEmbedder()
@ -21,7 +22,10 @@ def generate_random_negative_sample(all_dataset):
dataset: list of dicts
"""
len_dataset = len(all_dataset)
all_dataset_embeddings = [{'question_embedding': "", 'passage_positive_embedding': [], 'passage_negative_embeddings': []} for _ in range(len_dataset)]
all_dataset_embeddings = [{'question_embedding': "", 'passage_positive_embedding': []} for _ in range(len_dataset)]
all_embeddings = []
all_texts = []
print("calculate question embeddings")
# calculate question embeddings
@ -54,6 +58,8 @@ def generate_random_negative_sample(all_dataset):
for id in range(i, min(i + batch_size, len_dataset)):
for passage_id in range(len(all_dataset[id]['passage_positive'])):
all_dataset_embeddings[id]['passage_positive_embedding'].append(passage_positive_embeddings[count])
all_embeddings.append(passage_positive_embeddings[count])
all_texts.append(all_dataset[id]['passage_positive'][passage_id])
count += 1
print("calculate passage negative embeddings")
@ -70,26 +76,35 @@ def generate_random_negative_sample(all_dataset):
count = 0
for id in range(i, min(i + batch_size, len_dataset)):
for passage_id in range(len(all_dataset[id]['passage_negative'])):
all_dataset_embeddings[id]['passage_negative_embeddings'].append(passage_negative_embeddings[count])
all_embeddings.append(passage_negative_embeddings[count])
all_texts.append(all_dataset[id]['passage_negative'][passage_id])
count += 1
############ Create FAISS index ############
all_embeddings = np.array(all_embeddings, dtype=np.float32)
dim = all_embeddings.shape[1]
index = faiss.IndexFlatIP(dim)
faiss.normalize_L2(all_embeddings)
index.add(all_embeddings)
############ Get random hard negative passages ############
print("getting random negative passages")
for id in tqdm(range(len_dataset)):
not_valid_passages = all_dataset[id]['passage_negative'] + all_dataset[id]['passage_positive']
question_embeddings = all_dataset_embeddings[id]['question_embedding']
question_embeddings_normalized = np.array([question_embeddings], dtype=np.float32)
faiss.normalize_L2(question_embeddings_normalized)
passage_positive_embeddings = all_dataset_embeddings[id]['passage_positive_embedding'][0]
score_question_passage_positive = np.dot(question_embeddings, passage_positive_embeddings)
while len(all_dataset[id]['passage_negative_random']) < RANDOM_NEGATIVE_COUNT:
random_id = random.randint(0, len_dataset - 1)
if random_id != id:
all_passages_embedding = all_dataset_embeddings[random_id]['passage_negative_embeddings'] + all_dataset_embeddings[random_id]['passage_positive_embedding']
all_passages = all_dataset[random_id]['passage_negative'] + all_dataset[random_id]['passage_positive']
random_passage_id = random.randint(0, len(all_passages) - 1)
random_passage_embeddings = all_passages_embedding[random_passage_id]
score_question_random_passage = np.dot(question_embeddings, random_passage_embeddings)
if score_question_random_passage < THRESHOLD_MULTIPLY * score_question_passage_positive:
all_dataset[id]['passage_negative_random'].append(all_passages[random_passage_id])
num_retrieved = 30
vector_scores, vector_ids = index.search(question_embeddings_normalized, num_retrieved)
for vector_score, vector_id in zip(vector_scores[0], vector_ids[0]):
if (all_texts[vector_id] not in not_valid_passages) and (vector_score < THRESHOLD_MULTIPLY * score_question_passage_positive):
all_dataset[id]['passage_negative_random'].append(all_texts[vector_id])
if len(all_dataset[id]['passage_negative_random']) >= RANDOM_NEGATIVE_COUNT:
break
return all_dataset

View File

@ -90,7 +90,7 @@ def load_pquad_dataset():
return all_dataset
def remove_false_negative(dataset):
def remove_false_negative(dataset, random_negative_sample=False):
"""
remove false negative samples from synthetic dataset
Args:
@ -98,17 +98,22 @@ def remove_false_negative(dataset):
Returns:
dataset: list of dicts
"""
if random_negative_sample:
negative_name = "passage_negative_random"
else:
negative_name = "passage_negative"
# calculate passage negative embeddings
negative_count_all = 0
negative_count_removed = 0
len_dataset = len(dataset)
batch_size = 100
batch_size = 50
for i in tqdm(range(0, len_dataset, batch_size)):
question_list = []
passage_negative_list = []
for id in range(i, min(i + batch_size, len_dataset)):
for passage in dataset[id]['passage_negative']:
for passage in dataset[id][negative_name]:
question_list.append(dataset[id]['question'])
passage_negative_list.append(passage)
@ -120,11 +125,11 @@ def remove_false_negative(dataset):
count = 0
for id in range(i, min(i + batch_size, len_dataset)):
new_negative_list = []
for passage_id in range(len(dataset[id]['passage_negative'])):
for passage_id in range(len(dataset[id][negative_name])):
if results[count] == "0":
new_negative_list.append(dataset[id]['passage_negative'][passage_id])
new_negative_list.append(dataset[id][negative_name][passage_id])
count += 1
dataset[id]['passage_negative'] = new_negative_list
dataset[id][negative_name] = new_negative_list
print(f"removed {negative_count_removed} false negative samples from {negative_count_all} samples")
print("--------------------------------")
@ -145,40 +150,40 @@ def save_dataset(dataset, output_path):
def main(output_path):
#load synthetic dataset
print("--------------------------------")
print("loading synthetic dataset")
synthetic_train_path = "/home/firouzi/embedding_model/data_preprocess_notebook/data/synthetic-persian-qa-retrieval/train.jsonl"
synthetic_corpus_path = "/home/firouzi/embedding_model/data_preprocess_notebook/data/synthetic-persian-qa-retrieval/corpus.jsonl"
synthetic_queries_path = "/home/firouzi/embedding_model/data_preprocess_notebook/data/synthetic-persian-qa-retrieval/queries.jsonl"
# #load synthetic dataset
# print("--------------------------------")
# print("loading synthetic dataset")
# synthetic_train_path = "/home/firouzi/embedding_model/data_preprocess_notebook/data/synthetic-persian-qa-retrieval/train.jsonl"
# synthetic_corpus_path = "/home/firouzi/embedding_model/data_preprocess_notebook/data/synthetic-persian-qa-retrieval/corpus.jsonl"
# synthetic_queries_path = "/home/firouzi/embedding_model/data_preprocess_notebook/data/synthetic-persian-qa-retrieval/queries.jsonl"
synthetic_dataset = load_synthetic_dataset(synthetic_train_path, synthetic_queries_path, synthetic_corpus_path)
print(f"synthetic dataset loaded : {len(synthetic_dataset)} samples")
print("--------------------------------")
# synthetic_dataset = load_synthetic_dataset(synthetic_train_path, synthetic_queries_path, synthetic_corpus_path)
# print(f"synthetic dataset loaded : {len(synthetic_dataset)} samples")
# print("--------------------------------")
#load pquad dataset
print("loading pquad dataset")
pquad_dataset = load_pquad_dataset()
print(f"pquad dataset loaded : {len(pquad_dataset)} samples")
print("--------------------------------")
# #load pquad dataset
# print("loading pquad dataset")
# pquad_dataset = load_pquad_dataset()
# print(f"pquad dataset loaded : {len(pquad_dataset)} samples")
# print("--------------------------------")
# removing false negative samples from synthetic dataset
print("start to remove false negative samples from synthetic dataset")
synthetic_dataset = remove_false_negative(synthetic_dataset)
print(f"successfully removed false negative samples from synthetic dataset")
print("--------------------------------")
# # merge synthetic and pquad dataset
# print("start to merge synthetic and pquad dataset")
# all_dataset = synthetic_dataset + pquad_dataset
# print(f"successfully merged synthetic and pquad dataset")
# print("--------------------------------")
# removing false negative samples from pquad dataset
print("start to remove false negative samples from pquad dataset")
pquad_dataset = remove_false_negative(pquad_dataset)
print(f"successfully removed false negative samples from pquad dataset")
print("--------------------------------")
# # removing false negative samples from all dataset
# print("start to remove false negative samples from all dataset")
# all_dataset = remove_false_negative(all_dataset, random_negative_sample=False)
# print(f"successfully removed false negative samples from all dataset")
# print("--------------------------------")
# merge synthetic and pquad dataset
print("start to merge synthetic and pquad dataset")
all_dataset = synthetic_dataset + pquad_dataset
print(f"successfully merged synthetic and pquad dataset")
print("--------------------------------")
with open("/home/firouzi/embedding_model/data/train.json", "r", encoding="utf-8") as f:
all_dataset = json.load(f)
for i in range(len(all_dataset)):
all_dataset[i]['passage_negative_random'] = []
#generate random negative samples
print("start to generate random negative samples")
@ -186,6 +191,12 @@ def main(output_path):
print(f"successfully generated random negative samples")
print("--------------------------------")
# removing random false negative samples from all dataset
print("start to remove random false negative samples from all dataset")
all_dataset = remove_false_negative(all_dataset, random_negative_sample=True)
print(f"successfully removed random false negative samples from all dataset")
print("--------------------------------")
# save dataset
print("start to save dataset")
save_dataset(all_dataset, output_path)

View File

@ -34,7 +34,7 @@ class TextEmbedder:
"input": texts
}
responses = requests.post("http://78.38.161.78:3094/v1/embeddings", headers=self.headers, json=payload)
embeddings = [np.array(response["embedding"]) for response in responses.json()["data"]]
embeddings = [np.array(response["embedding"], dtype=np.float32) for response in responses.json()["data"]]
return embeddings

View File

@ -1,2 +1,3 @@
python-dotenv==1.1.1
hazm
hazm
faiss-cpu

View File

@ -271,6 +271,24 @@
"id": "4917b3a0",
"metadata": {},
"outputs": [],
"source": [
"import faiss\n",
"import numpy as np\n",
"\n",
"\n",
"x = np.array([1, 2, 3, 4, 5])\n",
"\n",
"faiss.normalize_L2(x)\n",
"\n",
"print(x)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ea9dcd98",
"metadata": {},
"outputs": [],
"source": []
}
],

View File

@ -0,0 +1,168 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 2,
"id": "96240870",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"سیاراتی که در مدار نزدیک به ستاره های کوتوله سرخ قرار دارند، به دلیل نزدیکی به ستاره مادر، تحت تابش تشعشعات شدید قرار می گیرند. این تابش می تواند شرایط زیست محیطی را به شدت تحت تأثیر قرار دهد و ممکن است تنها مکان هایی که حیات در آنجا امکان وجود دارد، زیر لایه های ضخیم یخ باشد. این شرایط می تواند مانع از شکل گیری و تکامل حیات در سطح سیاره شود.\n",
"{\"result\": \"0\"}\n",
"--------------------------------\n",
"کتاب تابستان به دلیل داستان جذاب و توصیف‌های زیبا از طبیعت و زندگی، توجه تمام علاقه‌مندان به ادبیات داستانی را به خود جلب می‌کند. این کتاب نه تنها احساسات عمیق انسانی را به تصویر می‌کشد بلکه خواننده را به دنیای خاطرات شیرین تابستان‌های کودکی می‌برد.\n",
"{{\"result\": \"0\"}}\n",
"\n",
"--------------------------------\n",
"حضرت ادریس علیه السلام به عنوان منشاء و معلم بسیاری از علوم شناخته می‌شود. او به عنوان یکی از قدیمی‌ترین پیشوایان علم، افکار بشر را به سمت استدلال و دقت در بحث سوق داده است. همچنین، او اولین کسی است که علم نجوم را به الهام الهی استخراج کرده و زمین را به چهار ربع تقسیم نموده است. در دعای روز اول ماه رجب نیز به علم ادریس اشاره شده است.\n",
"{\"result\": \"0\"}\n",
"--------------------------------\n",
"ستاره‌های کوتوله سرخ معمولاً به صورت دوره‌ای شعله‌هایی از پرتوهای ماورا بنفش و اشعه X ساطع می‌کنند که می‌تواند اتمسفر سیارات اطراف را از بین ببرد و احتمال تشکیل حیات را کاهش دهد. اما ستاره Ross 128 به عنوان یک ستاره آرام شناخته می‌شود و این ویژگی باعث می‌شود که شرایط بهتری برای تشکیل حیات در سیاره Ross 128b فراهم شود.\n",
"{\"result\": \"0\"}\n",
"--------------------------------\n",
"پوست کودکان به دلیل عدم تکامل کامل ملانوسیت‌ها، سیستم عروقی پوستی و توانایی تولید عرق حساس است. ملانوسیت‌ها که مسئول تولید ملانین هستند، از پوست در برابر اشعه ماورای بنفش محافظت می‌کنند. همچنین، سیستم عروقی پوستی در کودکان هنوز به طور کامل توسعه نیافته و این امر می‌تواند منجر به آسیب‌پذیری بیشتر پوست شود. علاوه بر این، پوست کودکان نمی‌تواند به اندازه کافی عرق تولید کند، که باعث می‌شود رطوبت پوست کاهش یابد. به همین دلیل، پوست کودکان به ویژه نوزادان به نسبت وزن بدن در معرض آسیب بیشتری قرار دارد.\n",
"{\"result\": \"0\"}\n",
"--------------------------------\n",
"نزول این آیه به واکنش‌های معاصرین پیامبر اسلام، به ویژه ابوجهل و دیگر مخالفان، اشاره دارد که به دلیل عدم درک صحیح از معانی عمیق آیات و قدرت خداوند، به تمسخر و انکار آن می‌پرداختند. این آیه به نوعی به آنها پاسخ می‌دهد و نشان می‌دهد که حتی در آتش، درختی وجود دارد که فراتر از تصور آنهاست. این واکنش‌ها نشان‌دهنده چالش‌های اعتقادی و فکری در آن زمان بود.\n",
"{\"result\": \"0\"}\n",
"--------------------------------\n",
"شرایط محیطی می‌تواند به عنوان فیلتر عمل کند زیرا عوامل متعددی مانند مقدار و نوع کالری، دما، اتمسفر، آب، خشکی، آفتاب، و بلایای طبیعی مانند آتشفشان و زلزله بر روی موجودات زنده تأثیر می‌گذارد. این عوامل می‌توانند موجودات را به چالش بکشند و تنها آن‌هایی که توانایی سازگاری با این شرایط را دارند، زنده می‌مانند و به نسل‌های بعدی منتقل می‌شوند.\n",
"{\"result\": \"0\"}\n",
"\n",
"--------------------------------\n",
"خشکی پوست ممکن است موقتی یا فصلی باشد. به عنوان مثال، در فصل زمستان به دلیل هوای سرد و خشک، بسیاری از افراد دچار خشکی پوست می‌شوند. در مقابل، در فصل‌های گرم و مرطوب، ممکن است این مشکل کاهش یابد. با این حال، برخی افراد ممکن است به طور دائمی با خشکی پوست مواجه باشند که نیاز به مراقبت و درمان مداوم دارد.\n",
"{\"result\": \"0\"}\n",
"--------------------------------\n",
"سحابی خرچنگ دریایی، که با نام NGC 6357 شناخته می‌شود، به دلیل وجود ستاره‌های غیرمعمول روشن و عظیم در آن، به عنوان یک مکان مهم در کهکشان معرفی می‌شود. این سحابی همچنین خوشۀ ستاره‌ای باز Pismis 24 را در نزدیکی مرکز خود دارد که نشان‌دهنده فعالیت‌های شدید ستاره‌زایی در این ناحیه است. درخشش آبی در نزدیکی منطقه تشکیل ستاره داخلی ناشی از انتشار گاز هیدروژن یونیزه است که به جذابیت این سحابی افزوده است.\n",
"{\"result\": \"0\"}\n",
"--------------------------------\n",
"سحابی خرچنگ ده سال نوری وسعت دارد و در مرکز آن یک تپ اختر قرار دارد. این تپ اختر به سنگینی خورشید اما به اندازه یک شهر کوچک است و ثانیه‌ای سی بار به دور خود می‌چرخد. همچنین، سحابی خرچنگ با سرعتی حدود 10000 کیلومتر بر ثانیه منبسط می‌شود و انتظار می‌رود که در چند هزار سال آینده به تدریج کم‌فروغ‌تر شده و سرانجام ناپدید گردد.\n",
"{\"result\": \"0\"}\n",
"--------------------------------\n",
"وجود یک اقیانوس زیر سطحی در قمر اروپا می تواند شرایط لازم برای زندگی موجودات میکروسکوپی را فراهم کند. این اقیانوس می تواند شامل مواد مغذی و حرارت لازم برای حیات باشد. با توجه به اینکه بخار آب فوران شده از سطح اروپا ممکن است به این اقیانوس مرتبط باشد، بررسی های آینده می تواند به دانشمندان کمک کند تا پتانسیل اروپا برای تبدیل شدن به یک محل قابل سکونت را بدون نیاز به حفاری لایه یخ بررسی کنند.\n",
"{{\"result\": \"0\"}}\n",
"--------------------------------\n",
"چگالش بوز-اینشتین حالتی از ماده است که در دماهای بسیار پایین ایجاد می‌شود و در آن اتم‌ها رفتار موجی خود را نشان می‌دهند. در این حالت، قوانین فیزیک کلاسیک به کنار می‌روند و فیزیک کوانتومی حاکم می‌شود. اتم‌ها در این حالت به گونه‌ای حرکت می‌کنند که انگار بر روی یکدیگر سوار هستند و این رفتار تنها در دماهای بسیار پایین قابل مشاهده است.\n",
"{\"result\": \"0\"}\n",
"--------------------------------\n",
"در سال 2012، انجمن سلطنتی شیمی مسابقه‌ای را برای یافتن بهترین توضیح برای اثر امپمبا برگزار کرد. برنده این مسابقه نظریه‌ای را ارائه داد که علت این پدیده را 'ابرسرد شدن' می‌دانست. این نشان می‌دهد که این موضوع همچنان مورد توجه محققان و دانشمندان است و تلاش‌ها برای درک بهتر آن ادامه دارد.\n",
"{\"result\": \"0\"}\n",
"--------------------------------\n",
"داستان کتاب عاشق آتشفشان در قرن هجدهم و در میان آشفتگی‌های دربار ناپلی اتفاق می‌افتد. این رمان به بررسی موضوعاتی چون عشق، تاریخ و روابط اجتماعی می‌پردازد و داستان زندگی سر ویلیام همیلتون و همسرش اِما را روایت می‌کند. همچنین، این داستان به تحولات سیاسی و اجتماعی آن زمان نیز اشاره دارد.\n",
"{\"result\": \"0\"}\n",
"--------------------------------\n",
"انفجارهای هوایی به دلیل قدرت تخریب بالای خود و نادر بودن برخورد سیارک‌ها، خطرناک‌تر محسوب می‌شوند. در حالی که برخورد سیارک‌های بزرگ به ندرت اتفاق می‌افتد، انفجارهای هوایی می‌توانند به طور ناگهانی و بدون هشدار پیشین رخ دهند. به عنوان مثال، انفجار سیارکی به اندازه یک خانه در سال ۱۳۹۲ در چلیابینسک روسیه منجر به آسیب دیدن بیش از ۱۶۰۰ نفر شد. این نشان می‌دهد که انفجارهای هوایی می‌توانند تأثیرات جدی بر روی جمعیت‌های انسانی داشته باشند.\n",
"{\"result\": \"0\"}\n",
"--------------------------------\n",
"پرتقال به دلیل خواص ضدعفونی‌کننده و ضد میکروبی که دارد، می‌تواند به درمان مشکلات پوستی کمک کند. به عنوان مثال، شما می‌توانید از پوست پرتقال له شده به عنوان مرهم برای اگزما و ناراحتی‌های پوستی استفاده کنید. این خاصیت به دلیل وجود ترکیبات طبیعی در پوست پرتقال است که به تسکین و بهبود وضعیت پوست کمک می‌کند.\n",
"{{\"result\": \"0\"}}\n",
"--------------------------------\n",
"نوسانات درخشندگی ستاره KIC 8462852 به‌طور نامنظم و شدید اتفاق می‌افتند و این الگو با آنچه معمولاً در ستاره‌های دارای سیارات فراخورشیدی مشاهده می‌شود، متفاوت است. در حالی که وجود یک سیاره می‌تواند باعث نوسانات درخشندگی شود، در این مورد، نوسانات به‌قدری پیچیده و غیرقابل پیش‌بینی هستند که فرضیه‌های دیگر مانند وجود ابرهای میان ستاره‌ای، دنباله‌دارها یا حتی اَبَرسازه‌های بیگانگان فضایی نیز مطرح شده‌اند.\n",
"{\"result\": \"0\"}\n",
"--------------------------------\n",
"پاریس به عنوان یک مقصد گردشگری محبوب به دلیل جاذبه‌های تاریخی، فرهنگی و هنری خود شناخته می‌شود. این شهر با برج ایفل، موزه لوور، کاتدرال نوتردام و خیابان‌های زیبا و پر از زندگی، هر ساله میلیون‌ها گردشگر را به خود جذب می‌کند. همچنین، فرهنگ غنی، غذاهای لذیذ و فضاهای رمانتیک پاریس، تجربه‌ای منحصر به فرد را برای بازدیدکنندگان فراهم می‌آورد. به همین دلیل، پاریس به عنوان 'شهر نور' و 'شهر عشق' در قلب بسیاری از مردم جهان جای دارد.\n",
"{\"result\": \"0\"}\n",
"--------------------------------\n"
]
}
],
"source": [
"import requests\n",
"from dotenv import load_dotenv\n",
"import os\n",
"import re\n",
"\n",
"load_dotenv()\n",
"\n",
"qwen = False\n",
"if qwen:\n",
" url = \"https://qwen3.chatllm.aiengines.ir/v1/chat/completions\"\n",
" model = \"Qwen/Qwen3-4B-Instruct-2507\"\n",
" headers = {\"Content-Type\": \"application/json\", \"Authorization\": f\"Bearer {os.getenv('LLM_AS_RERANKER_PASS')}\"}\n",
"else:\n",
" url = \"http://192.168.130.206:4001/v1/chat/completions\"\n",
" model = \"google/gemma-3-27b-it\"\n",
" headers = {\"Content-Type\": \"application/json\"}\n",
"\n",
"instruction = \"\"\"\n",
"You are a helpful assistant that help me to find that the text is relevant to the question or not.\n",
"You are given a question and a text.\n",
"You must evaluate the text based on the question and return \"1\" if the text is relevant to the question and \"0\" if the text is not relevant to the question.\n",
" \n",
"be carefull, I have chosen the text randomly from my dataset so the text must answer the question independently.\n",
"You must return the result in the following format:\n",
"{{\"result\": \"1\" or \"0\"}}\n",
"\"\"\"\n",
"\n",
"question = \"چرا خورشید اینقدر داغ است؟\"\n",
"texts = [\n",
" \"سیاراتی که در مدار نزدیک به ستاره های کوتوله سرخ قرار دارند، به دلیل نزدیکی به ستاره مادر، تحت تابش تشعشعات شدید قرار می گیرند. این تابش می تواند شرایط زیست محیطی را به شدت تحت تأثیر قرار دهد و ممکن است تنها مکان هایی که حیات در آنجا امکان وجود دارد، زیر لایه های ضخیم یخ باشد. این شرایط می تواند مانع از شکل گیری و تکامل حیات در سطح سیاره شود.\",\n",
" \"کتاب تابستان به دلیل داستان جذاب و توصیف‌های زیبا از طبیعت و زندگی، توجه تمام علاقه‌مندان به ادبیات داستانی را به خود جلب می‌کند. این کتاب نه تنها احساسات عمیق انسانی را به تصویر می‌کشد بلکه خواننده را به دنیای خاطرات شیرین تابستان‌های کودکی می‌برد.\",\n",
" \"حضرت ادریس علیه السلام به عنوان منشاء و معلم بسیاری از علوم شناخته می‌شود. او به عنوان یکی از قدیمی‌ترین پیشوایان علم، افکار بشر را به سمت استدلال و دقت در بحث سوق داده است. همچنین، او اولین کسی است که علم نجوم را به الهام الهی استخراج کرده و زمین را به چهار ربع تقسیم نموده است. در دعای روز اول ماه رجب نیز به علم ادریس اشاره شده است.\",\n",
" \"ستاره‌های کوتوله سرخ معمولاً به صورت دوره‌ای شعله‌هایی از پرتوهای ماورا بنفش و اشعه X ساطع می‌کنند که می‌تواند اتمسفر سیارات اطراف را از بین ببرد و احتمال تشکیل حیات را کاهش دهد. اما ستاره Ross 128 به عنوان یک ستاره آرام شناخته می‌شود و این ویژگی باعث می‌شود که شرایط بهتری برای تشکیل حیات در سیاره Ross 128b فراهم شود.\",\n",
" \"پوست کودکان به دلیل عدم تکامل کامل ملانوسیت‌ها، سیستم عروقی پوستی و توانایی تولید عرق حساس است. ملانوسیت‌ها که مسئول تولید ملانین هستند، از پوست در برابر اشعه ماورای بنفش محافظت می‌کنند. همچنین، سیستم عروقی پوستی در کودکان هنوز به طور کامل توسعه نیافته و این امر می‌تواند منجر به آسیب‌پذیری بیشتر پوست شود. علاوه بر این، پوست کودکان نمی‌تواند به اندازه کافی عرق تولید کند، که باعث می‌شود رطوبت پوست کاهش یابد. به همین دلیل، پوست کودکان به ویژه نوزادان به نسبت وزن بدن در معرض آسیب بیشتری قرار دارد.\",\n",
" \"نزول این آیه به واکنش‌های معاصرین پیامبر اسلام، به ویژه ابوجهل و دیگر مخالفان، اشاره دارد که به دلیل عدم درک صحیح از معانی عمیق آیات و قدرت خداوند، به تمسخر و انکار آن می‌پرداختند. این آیه به نوعی به آنها پاسخ می‌دهد و نشان می‌دهد که حتی در آتش، درختی وجود دارد که فراتر از تصور آنهاست. این واکنش‌ها نشان‌دهنده چالش‌های اعتقادی و فکری در آن زمان بود.\",\n",
" \"شرایط محیطی می‌تواند به عنوان فیلتر عمل کند زیرا عوامل متعددی مانند مقدار و نوع کالری، دما، اتمسفر، آب، خشکی، آفتاب، و بلایای طبیعی مانند آتشفشان و زلزله بر روی موجودات زنده تأثیر می‌گذارد. این عوامل می‌توانند موجودات را به چالش بکشند و تنها آن‌هایی که توانایی سازگاری با این شرایط را دارند، زنده می‌مانند و به نسل‌های بعدی منتقل می‌شوند.\",\n",
" \"خشکی پوست ممکن است موقتی یا فصلی باشد. به عنوان مثال، در فصل زمستان به دلیل هوای سرد و خشک، بسیاری از افراد دچار خشکی پوست می‌شوند. در مقابل، در فصل‌های گرم و مرطوب، ممکن است این مشکل کاهش یابد. با این حال، برخی افراد ممکن است به طور دائمی با خشکی پوست مواجه باشند که نیاز به مراقبت و درمان مداوم دارد.\",\n",
" \"سحابی خرچنگ دریایی، که با نام NGC 6357 شناخته می‌شود، به دلیل وجود ستاره‌های غیرمعمول روشن و عظیم در آن، به عنوان یک مکان مهم در کهکشان معرفی می‌شود. این سحابی همچنین خوشۀ ستاره‌ای باز Pismis 24 را در نزدیکی مرکز خود دارد که نشان‌دهنده فعالیت‌های شدید ستاره‌زایی در این ناحیه است. درخشش آبی در نزدیکی منطقه تشکیل ستاره داخلی ناشی از انتشار گاز هیدروژن یونیزه است که به جذابیت این سحابی افزوده است.\",\n",
" \"سحابی خرچنگ ده سال نوری وسعت دارد و در مرکز آن یک تپ اختر قرار دارد. این تپ اختر به سنگینی خورشید اما به اندازه یک شهر کوچک است و ثانیه‌ای سی بار به دور خود می‌چرخد. همچنین، سحابی خرچنگ با سرعتی حدود 10000 کیلومتر بر ثانیه منبسط می‌شود و انتظار می‌رود که در چند هزار سال آینده به تدریج کم‌فروغ‌تر شده و سرانجام ناپدید گردد.\",\n",
" \"وجود یک اقیانوس زیر سطحی در قمر اروپا می تواند شرایط لازم برای زندگی موجودات میکروسکوپی را فراهم کند. این اقیانوس می تواند شامل مواد مغذی و حرارت لازم برای حیات باشد. با توجه به اینکه بخار آب فوران شده از سطح اروپا ممکن است به این اقیانوس مرتبط باشد، بررسی های آینده می تواند به دانشمندان کمک کند تا پتانسیل اروپا برای تبدیل شدن به یک محل قابل سکونت را بدون نیاز به حفاری لایه یخ بررسی کنند.\",\n",
" \"چگالش بوز-اینشتین حالتی از ماده است که در دماهای بسیار پایین ایجاد می‌شود و در آن اتم‌ها رفتار موجی خود را نشان می‌دهند. در این حالت، قوانین فیزیک کلاسیک به کنار می‌روند و فیزیک کوانتومی حاکم می‌شود. اتم‌ها در این حالت به گونه‌ای حرکت می‌کنند که انگار بر روی یکدیگر سوار هستند و این رفتار تنها در دماهای بسیار پایین قابل مشاهده است.\",\n",
" \"در سال 2012، انجمن سلطنتی شیمی مسابقه‌ای را برای یافتن بهترین توضیح برای اثر امپمبا برگزار کرد. برنده این مسابقه نظریه‌ای را ارائه داد که علت این پدیده را 'ابرسرد شدن' می‌دانست. این نشان می‌دهد که این موضوع همچنان مورد توجه محققان و دانشمندان است و تلاش‌ها برای درک بهتر آن ادامه دارد.\",\n",
" \"داستان کتاب عاشق آتشفشان در قرن هجدهم و در میان آشفتگی‌های دربار ناپلی اتفاق می‌افتد. این رمان به بررسی موضوعاتی چون عشق، تاریخ و روابط اجتماعی می‌پردازد و داستان زندگی سر ویلیام همیلتون و همسرش اِما را روایت می‌کند. همچنین، این داستان به تحولات سیاسی و اجتماعی آن زمان نیز اشاره دارد.\",\n",
" \"انفجارهای هوایی به دلیل قدرت تخریب بالای خود و نادر بودن برخورد سیارک‌ها، خطرناک‌تر محسوب می‌شوند. در حالی که برخورد سیارک‌های بزرگ به ندرت اتفاق می‌افتد، انفجارهای هوایی می‌توانند به طور ناگهانی و بدون هشدار پیشین رخ دهند. به عنوان مثال، انفجار سیارکی به اندازه یک خانه در سال ۱۳۹۲ در چلیابینسک روسیه منجر به آسیب دیدن بیش از ۱۶۰۰ نفر شد. این نشان می‌دهد که انفجارهای هوایی می‌توانند تأثیرات جدی بر روی جمعیت‌های انسانی داشته باشند.\",\n",
" \"پرتقال به دلیل خواص ضدعفونی‌کننده و ضد میکروبی که دارد، می‌تواند به درمان مشکلات پوستی کمک کند. به عنوان مثال، شما می‌توانید از پوست پرتقال له شده به عنوان مرهم برای اگزما و ناراحتی‌های پوستی استفاده کنید. این خاصیت به دلیل وجود ترکیبات طبیعی در پوست پرتقال است که به تسکین و بهبود وضعیت پوست کمک می‌کند.\",\n",
" \"نوسانات درخشندگی ستاره KIC 8462852 به‌طور نامنظم و شدید اتفاق می‌افتند و این الگو با آنچه معمولاً در ستاره‌های دارای سیارات فراخورشیدی مشاهده می‌شود، متفاوت است. در حالی که وجود یک سیاره می‌تواند باعث نوسانات درخشندگی شود، در این مورد، نوسانات به‌قدری پیچیده و غیرقابل پیش‌بینی هستند که فرضیه‌های دیگر مانند وجود ابرهای میان ستاره‌ای، دنباله‌دارها یا حتی اَبَرسازه‌های بیگانگان فضایی نیز مطرح شده‌اند.\",\n",
" \"پاریس به عنوان یک مقصد گردشگری محبوب به دلیل جاذبه‌های تاریخی، فرهنگی و هنری خود شناخته می‌شود. این شهر با برج ایفل، موزه لوور، کاتدرال نوتردام و خیابان‌های زیبا و پر از زندگی، هر ساله میلیون‌ها گردشگر را به خود جذب می‌کند. همچنین، فرهنگ غنی، غذاهای لذیذ و فضاهای رمانتیک پاریس، تجربه‌ای منحصر به فرد را برای بازدیدکنندگان فراهم می‌آورد. به همین دلیل، پاریس به عنوان 'شهر نور' و 'شهر عشق' در قلب بسیاری از مردم جهان جای دارد.\"\n",
" ]\n",
" \n",
"for text in texts:\n",
" input_message = f\"\"\"{{\"question\": \"{question}\", \"text\": \"{text}\"}}\"\"\"\n",
" messages = [{\"role\": \"system\", \"content\": instruction}, {\"role\": \"user\", \"content\": input_message}]\n",
"\n",
" payload = {\n",
" \"model\": model,\n",
" \"messages\": messages,\n",
" \"max_tokens\": 100\n",
" }\n",
"\n",
" req = requests.post(url, headers=headers, json=payload)\n",
" print(text)\n",
" print(req.json()['choices'][0]['message']['content'])\n",
" print(\"--------------------------------\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "53e5e322",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@ -0,0 +1,178 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "16798408",
"metadata": {},
"outputs": [],
"source": [
"import json\n",
"\n",
"with open(\"/home/firouzi/embedding_model/data/train_100.json\", \"r\", encoding=\"utf-8\") as f:\n",
" all_dataset = json.load(f)\n",
"\n",
"data_count = []\n",
"for data in all_dataset:\n",
" data_count.append(len(data[\"passage_negative\"]) + len(data[\"passage_negative_random\"]))\n",
"\n",
"\n",
"counts = {}\n",
"\n",
"for num in data_count:\n",
" if num in counts:\n",
" counts[num] += 1\n",
" else:\n",
" counts[num] = 1"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "a0eb428f",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{8: 22, 6: 11, 7: 20, 9: 46, 5: 1}"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"counts"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "ca0412d2",
"metadata": {},
"outputs": [],
"source": [
"from datasets import Dataset\n",
"\n",
"with open(\"/home/firouzi/embedding_model/data/train_100.json\", \"r\", encoding=\"utf-8\") as f:\n",
" all_dataset = json.load(f)\n",
"\n",
"anchors = []\n",
"positives = []\n",
"negatives_1 = []\n",
"negatives_2 = []\n",
"negatives_3 = []\n",
"negatives_4 = []\n",
"negatives_5 = []\n",
"for data in all_dataset:\n",
" anchors.append(data[\"question\"])\n",
" positives.append(data[\"passage_positive\"])\n",
" all_negatives = data[\"passage_negative\"] + data[\"passage_negative_random\"]\n",
" if len(all_negatives) < 5:\n",
" for i in range(5 - len(all_negatives)):\n",
" all_negatives.append(all_negatives[0])\n",
" negatives_1.append(all_negatives[0])\n",
" negatives_2.append(all_negatives[1])\n",
" negatives_3.append(all_negatives[2])\n",
" negatives_4.append(all_negatives[3])\n",
" negatives_5.append(all_negatives[4])\n",
"\n",
"dataset = Dataset.from_dict({\n",
" \"anchor\": anchors,\n",
" \"positive\": positives,\n",
" \"negative_1\": negatives_1,\n",
" \"negative_2\": negatives_2,\n",
" \"negative_3\": negatives_3,\n",
" \"negative_4\": negatives_4,\n",
" \"negative_5\": negatives_5,\n",
"})\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "cc963d18",
"metadata": {},
"outputs": [],
"source": [
"dataset_split = dataset.train_test_split(test_size=0.05, seed=42)\n",
"\n",
"train_dataset = dataset_split[\"train\"]\n",
"test_dataset = dataset_split[\"test\"]"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "593f7ce4",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"95"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"len(train_dataset)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "f0443056",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"5"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"len(test_dataset)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "377f53ba",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

128
train/jina/jina_train.py Normal file
View File

@ -0,0 +1,128 @@
from datasets import Dataset
import json
from sentence_transformers import (
SentenceTransformer,
SentenceTransformerTrainer,
SentenceTransformerTrainingArguments,
)
from sentence_transformers.losses import MultipleNegativesRankingLoss
from sentence_transformers.training_args import BatchSamplers
from sentence_transformers.evaluation import RerankingEvaluator
########### Load model ###########
# 1. Load a model to finetune with 2. (Optional) model card data
model = SentenceTransformer("jinaai/jina-embeddings-v3",
trust_remote_code=True,
local_files_only=False,
model_kwargs={'default_task': 'retrieval'})
########### Load dataset ###########
# 3. Load a dataset to finetune on
with open("/home/firouzi/embedding_model/data/train_100.json", "r", encoding="utf-8") as f:
all_dataset = json.load(f)
anchors = []
positives = []
negatives_1 = []
negatives_2 = []
negatives_3 = []
negatives_4 = []
negatives_5 = []
for data in all_dataset:
anchors.append(data["question"])
positives.append(data["passage_positive"])
all_negatives = data["passage_negative"] + data["passage_negative_random"]
if len(all_negatives) < 5:
for i in range(5 - len(all_negatives)):
all_negatives.append(all_negatives[0])
negatives_1.append(all_negatives[0])
negatives_2.append(all_negatives[1])
negatives_3.append(all_negatives[2])
negatives_4.append(all_negatives[3])
negatives_5.append(all_negatives[4])
dataset = Dataset.from_dict({
"anchor": anchors,
"positive": positives,
"negative_1": negatives_1,
"negative_2": negatives_2,
"negative_3": negatives_3,
"negative_4": negatives_4,
"negative_5": negatives_5,
})
dataset_split = dataset.train_test_split(test_size=0.05, seed=42)
train_dataset = dataset_split["train"]
eval_dataset = dataset_split["test"]
########### Load loss function ###########
# 4. Define a loss function
loss = MultipleNegativesRankingLoss(model)
########### Load training arguments ###########
# 5. (Optional) Specify training arguments
args = SentenceTransformerTrainingArguments(
# Required parameter:
output_dir="models/jina_v3",
# Optional training parameters:
num_train_epochs=1,
per_device_train_batch_size=16,
per_device_eval_batch_size=16,
learning_rate=2e-5,
warmup_ratio=0.1,
fp16=True, # Set to False if you get an error that your GPU can't run on FP16
bf16=False, # Set to True if you have a GPU that supports BF16
batch_sampler=BatchSamplers.NO_DUPLICATES, # MultipleNegativesRankingLoss benefits from no duplicate samples in a batch
# Optional tracking/debugging parameters:
eval_strategy="steps",
eval_steps=100,
save_strategy="steps",
save_steps=100,
save_total_limit=2,
logging_steps=100,
run_name="jina_v3", # Will be used in W&B if `wandb` is installed
)
########### Load evaluator ###########
# 6. (Optional) Create an evaluator & evaluate the base model
eval_dataset_evaluator = [
{
"query": sample["anchor"],
"positive": [sample["positive"]],
"negative": [sample["negative_1"], sample["negative_2"], sample["negative_3"], sample["negative_4"], sample["negative_5"]],
}
for sample in eval_dataset
]
dev_evaluator = RerankingEvaluator(
name="jina_v3",
samples=eval_dataset_evaluator,
)
dev_evaluator(model)
########### Load trainer ###########
# 7. Create a trainer & train
trainer = SentenceTransformerTrainer(
model=model,
args=args,
train_dataset=train_dataset,
eval_dataset=eval_dataset,
loss=loss,
evaluator=dev_evaluator,
)
trainer.train()
########### Load test evaluator ###########
# (Optional) Evaluate the trained model on the test set
# test_evaluator = TripletEvaluator(
# anchors=test_dataset["anchor"],
# positives=test_dataset["positive"],
# negatives=test_dataset["negative"],
# name="all-nli-test",
# )
# test_evaluator(model)
########### Save the trained model ###########
# 8. Save the trained model
model.save_pretrained("models/jina_v3")