import logging import torch from transformers import MarkupLMProcessor, MarkupLMFeatureExtractor from consts import id2label from download import NewsHtmlDowloader from processor import NewsProcessor from utils import TextUtils from cache import Singleton class NewsInference: """ NewsInference sınıfı, haberlerin tahmin edilmesi için gerekli işlemleri gerçekleştirir. Args: None Attributes: __downloader (NewsHtmlDowloader): Haberleri indirmek için kullanılan NewsHtmlDowloader nesnesi. __news_processor (NewsProcessor): Haberlerin işlenmesi için kullanılan NewsProcessor nesnesi. __utils (TextUtils): Metin işleme işlemleri için kullanılan TextUtils nesnesi. __feature_extractor (MarkupLMFeatureExtractor): Özellik çıkarımı için kullanılan MarkupLMFeatureExtractor nesnesi. __markuplm_processor: Ön eğitimli MarkupLMProcessor nesnesi. __cache (Singleton): Model önbelleğe almak için kullanılan Singleton nesnesi. device (torch.device): Kullanılan cihaz (cuda: GPU veya cpu: CPU). Methods: __init__(): Sınıfın başlatılması için kullanılan yöntem. __load_model(): Modelin yüklenmesi için kullanılan özel yöntem. __prepare(url): Haber verilerinin hazırlanması için kullanılan özel yöntem. __process(encoding, nodes, model): Haber tahmininin gerçekleştirilmesi için kullanılan özel yöntem. predict(url): Verilen URL'e göre haber tahmini gerçekleştiren yöntem. """ __downloader: NewsHtmlDowloader = None __news_processor: NewsProcessor = None __utils: TextUtils = None __feature_extractor: MarkupLMFeatureExtractor = None __markuplm_processor = None __cache = Singleton() device = torch.device("cuda" if torch.cuda.is_available() else "cpu") def __init__(self): """ NewsInference sınıfının başlatılması için kullanılan yöntem. İlgili nesnelerin oluşturulması ve modelin yüklenmesi işlemlerini gerçekleştirir. Args: None Returns: None """ self.__downloader = NewsHtmlDowloader() self.__news_processor = NewsProcessor() self.__utils = TextUtils() self.__feature_extractor = MarkupLMFeatureExtractor() self.__markuplm_processor = MarkupLMProcessor.from_pretrained("microsoft/markuplm-base") self.__markuplm_processor.parse_html = False logging.debug('NewsInference Sınıfı oluşturuldu') def __load_model(self): """ Modelin önbellekten yüklenmesi için kullanılan özel yöntem. Args: None Returns: Model: Önceden eğitilmiş model. """ return self.__cache.load_model() def __prepare(self, url): """ Verilen URL'e göre haber verilerinin hazırlanması için kullanılan özel yöntem. Args: url (str): Haberin URL'i. Returns: tuple: Hazırlanan kodlama, düğümler ve xpath'lerin bir tuple'ı. """ html = self.__downloader.download(url) clean_html = self.__news_processor.transform(html) features = self.__feature_extractor(clean_html) nodes_o = features['nodes'] nodes = [[]] xpaths = features["xpaths"] for node_text in nodes_o[0]: node_text = self.__utils.clean_format_str(node_text) nodes[0].append(node_text) encoding = self.__markuplm_processor(nodes=nodes, xpaths=xpaths, return_offsets_mapping=True, truncation=True, return_tensors="pt").to(self.device) return encoding, nodes_o, xpaths def __process(self, encoding, nodes, model): """ Haber verilerinin işlenmesi ve tahmin yapılması için kullanılan özel yöntem. Args: encoding (Encoding): Hazırlanan kodlama. nodes (list): Haber düğümleri. model (Model): Haber tahmini için kullanılan model. Returns: dict: Tahmin sonuçları. """ offset_mapping = encoding.pop("offset_mapping") with torch.no_grad(): outputs = model(**encoding) m = torch.nn.Softmax(dim=-1) predictions = outputs.logits.argmax(-1) props = m(outputs.logits) data = { "date": [], "title": [], "description": [], "content": [], "other": [] } for pred_id, prop, word_id, offset in zip(predictions[0].tolist(), props[0].tolist(), encoding.word_ids(0), offset_mapping[0].tolist()): if word_id is not None and offset[0] == 0: label = id2label[pred_id] value = nodes[0][word_id] score = prop[pred_id] if label == "content": value = self.__news_processor.decode(value) value = self.__utils.text_space_normalizer(value) if label == "date": parsed = self.__utils.parse_date_time(value) if parsed: value = parsed else: score = 0.0 value = "" item = {"value": value, "score": score} data[label].append(item) date = max(data["date"], key=lambda x: x['score']) if len(data["date"]) > 0 else None title = max(data["title"], key=lambda x: x['score']) if len(data["title"]) > 0 else None description = max(data["description"], key=lambda x: x['score']) if len(data["description"]) > 0 else None content = max(data["content"], key=lambda x: x['score']) if len(data["content"]) > 0 else None response = { "date": date, "title": title, "description": description, "content": content } return response def predict(self, url): """ Verilen URL'e göre haber tahmini gerçekleştiren yöntem. Args: url (str): Haberin URL'i. Returns: dict: Tahmin sonuçları. """ try: model = self.__load_model() encoding, nodes, xpaths = self.__prepare(url) return self.__process(encoding, nodes, model) except Exception as e: logging.info(f"An exception occurred id: {url} error: {str(e)}") if __name__ == '__main__': inference = NewsInference() # url = "https://www.aa.com.tr/tr/bilim-teknoloji/ab-ile-google-yapay-zeka-anlasmasi-hazirliginda/2905068" url = "https://www.hurriyet.com.tr/dunya/beyaz-saraydan-rusyaya-tutuklu-bulunan-wall-street-journal-muhabiri-tepkisi-42272803" inference.predict(url)