Skip to content

Commit

Permalink
🧹 Remove summarization functionality
Browse files Browse the repository at this point in the history
Deleted the unused `extract_urlnews` function and related imports from `helpers.py`. Removed the `/completion` and `/extract` endpoints along with unnecessary imports from `app.py`. Simplified `handle_context_window_error` in `llm.py` and cleaned up evaluation print statements. Updated default output file name in `predictor.py` and removed unused prompts and models.
  • Loading branch information
redadmiral committed Oct 1, 2024
1 parent 44319c2 commit 81c769c
Show file tree
Hide file tree
Showing 7 changed files with 13 additions and 160 deletions.
93 changes: 5 additions & 88 deletions app.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,24 @@
import asyncio
import json
import logging
import re
from uuid import uuid4

import uvicorn
from fastapi.responses import StreamingResponse, RedirectResponse, JSONResponse
from newspaper.article import ArticleException
from fastapi.responses import RedirectResponse
from openai import OpenAI, AsyncOpenAI

from src.auditor import Auditor
from src.config import app, LOGGING_CONFIG
from src.datastructures import (
GenerationRequest,
CheckResponse,
CheckRequest,
CheckResponseItem,
)
from src.datastructures import OpenAiModel
from src.helpers import extract_urlnews
from src.llm import handle_stream, tool_chain, call_openai_lin
from src.llm import call_openai_lin
from src.prompts import (
system_prompt_honest,
system_prompt_malicious,
check_prompt,
detect_language,
check_content,
invalid_input_response,
english_response
)

Expand All @@ -48,61 +40,9 @@ async def docs_redirect():
return RedirectResponse(url="/docs")


@app.post("/completion", response_model=str)
async def completion(
request: GenerationRequest,
model: OpenAiModel = OpenAiModel.gpt4mini,
honest: bool = True,
raw_output: bool = False,
output_language: str = 'German'
):
"""
Completion endpoint for text generation.
:param request: Input data to generate text.
:param model: Model to be used for generation.
:param honest: Flag to select between system prompts.
:param raw_output: Flag to control the format of the output.
:returns: A streaming response of generated text.
:raises keyError: Raises an exception on key retrieval error.
"""

# User input text
prompt = request.source
# Detect language
messages = [[{"role": "system", "content": detect_language}],
[{"role": "system", "content": check_content}]]
tasks = [call_openai_lin(prompt=prompt, messages=message, client=async_client, model=model) for message in messages]
resp = await asyncio.gather(*tasks)
input_language = resp[0].choices[0].message.content
output_language = json.loads(input_language)['language']
content_status = resp[1].choices[0].message.content
# Print the response
print(f'{input_language}, {content_status}')
if not json.loads(content_status)['content_status'] == "valid":
return StreamingResponse(
handle_stream(invalid_input_response,
all_json=~raw_output),
)

system_prompt = system_prompt_malicious

if output_language == 'English':
system_prompt += english_response

messages = [{"role": "system", "content": system_prompt}]
# logging.debug(request)
return StreamingResponse(
handle_stream(
tool_chain(client, request.source, messages, model=model),
all_json= not raw_output),
media_type="text/event-stream",
)


@app.post("/check", response_model=CheckResponse)
def check_article_against_source(
request: CheckRequest, model: OpenAiModel = OpenAiModel.gpt4mini, output_language = "German"
request: CheckRequest, model: OpenAiModel = OpenAiModel.gpt4mini, output_language="German"
):
"""
The endpoint compares a given article chunk against a source using an AI model to determine its validity.
Expand All @@ -115,15 +55,15 @@ def check_article_against_source(
system_prompt_check = check_prompt if output_language == "German" else check_prompt + english_response

fc = Auditor(request.source, request.chunk)
logging.info( # f'\n\nChecking against each PARAGRAPH that contains similar sentences\n\n'
logging.info(
f"Input:\n{fc.input}\n\n" f"{len(fc.similar_para_id)} similar paragraph(s)\n"
)

answers = []

# Joining similar paragraphs
similar_paras = '\n\n'.join([fc.paragraphs[para_id] for para_id in fc.similar_para_id])

messages = [{"role": "system", "content": system_prompt_check}]
prompt = "Satz:\n" f"{fc.input}\n\n" "Ausgangstext:\n" f"{similar_paras}"

Expand All @@ -144,7 +84,6 @@ def check_article_against_source(
if (len(answers) == 0): # No paragraphs are similar enough to be compared by the LLM
reason = "Die Behauptung ist nicht im Text enthalten."

# print(f'\nResult: {result}\nSentence: {request.chunk}\nReason: {reason}\nAnswers: {answers}')
print(f'\nResult: {result}\nSentence: {request.chunk}\nReason: {reason}')
return CheckResponse(
id=request.id,
Expand All @@ -155,27 +94,5 @@ def check_article_against_source(
)


@app.post("/extract", response_model=str)
def extract_article_from_url(url):
"""
Handles POST requests to extract article information from a given URL.
:param url: The URL of the article
:returns: The JSON response containing the article headline, text, and image links, or error message on failure
:raises: Returns a JSON response with an error message if extraction fails
"""
try:
headline, text, image_links = extract_urlnews(url)
except ArticleException as e:
return json.dumps(
{"status": "failure", "error": f"Cannot fetch or parse the URL: {str(e)}"}
)

article = {"headline": headline, "text": text, "image_links": image_links}

logging.debug(article)
return JSONResponse(content=article)


if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=3000, log_config=LOGGING_CONFIG)
8 changes: 4 additions & 4 deletions evaluation/evaluation.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
#print(f"Detected Hallucinations {file}: {hal_detected/ hallucination}")
#print(f"Level 1 Hallucinations detected {file}: {low_hal_detected/ low_hallu}")
#print("\n")
print(f"Precision: {precision}")
print(f"Recall: {recall}")
print(f"F_0.5-score (precision twice as important as recall): {(1+.5**2)*(recall*precision)/((.5**2)*recall+precision)}")
print(f"F_1-score (precision as important as recall): {2*(recall*precision)/(recall+precision)}")
print(f"Precision: {round(precision, 4)*100}%")
print(f"Recall: {round(recall, 4)*100}%")
print(f"F_0.5-score (precision twice as important as recall): {round((1+.5**2)*(recall*precision)/((.5**2)*recall+precision), 4)*100}%")
print(f"F_1-score (precision as important as recall): {round(2*(recall*precision)/(recall+precision), 4)*100}%")
2 changes: 1 addition & 1 deletion evaluation/predictor.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
lines = f.readlines()
checked = [x.strip() for x in lines]

OUTPUT_FILE = "gpt35_result"
OUTPUT_FILE = "niels_result"

processed = []
try:
Expand Down
7 changes: 1 addition & 6 deletions src/datastructures.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@
from pydantic import BaseModel


class GenerationRequest(BaseModel):
source: str
query_id: uuid.UUID = uuid.uuid4()


class CheckRequest(BaseModel):
id: uuid.UUID = uuid.uuid4()
source: str
Expand All @@ -33,4 +28,4 @@ class CheckResponse(BaseModel):
class OpenAiModel(Enum):
gpt35turbo = "gpt-3.5-turbo"
gpt4turbo = "gpt-4-turbo"
gpt4mini= "gpt-4o-mini"
gpt4mini = "gpt-4o-mini"
29 changes: 0 additions & 29 deletions src/helpers.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
from typing import List

import spacy
from bs4 import BeautifulSoup
from newspaper import Article
from numpy import dot
from numpy.linalg import norm

Expand All @@ -29,30 +27,3 @@ def split_sentences(text) -> List[str]:
"""
doc = nlp(text)
return [x.text for x in doc.sents]


def extract_urlnews(url) -> List[str]:
"""
Extract the title, text, and image URLs from a news article URL.
:param url: The URL of the news article to extract data from.
:returns: A tuple containing the article's title, text, and a list of image URLs.
"""
article = Article(url)
article.download()
article.parse()

# Use BeautifulSoup to parse the images
soup = BeautifulSoup(article.html, 'html.parser')
images = soup.find_all('img')
article_images = []
for image in images:
src = image.get('data-src') or image.get('data-srcset') or image.get('src')
if src and src.startswith('http'):
article_images.append(src)

# Filter out SVG images and data URI images
article_images = [img for img in article_images if
not (img.lower().endswith('.svg') or img.lower().startswith('data:image/svg+xml'))]

return article.title, article.text, article_images
6 changes: 2 additions & 4 deletions src/llm.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ def handle_stream(stream, all_json=False, json_pp: bool = False):

def handle_context_window_error(client, prompt, messages, model):
"""
Handles context window errors by truncating the messages list.
:param client: OpenAI client instance to be used
Expand All @@ -72,9 +71,8 @@ def handle_context_window_error(client, prompt, messages, model):
:param model: The OpenAI model to be called
:returns: The result from the OpenAI model call
"""
for i in range(1, len(messages) - 1):
messages = [messages[0], messages[-1]]
messages.pop(i)

messages = [messages[0], messages[-1]]
return call_openai(client, prompt, messages, model)


Expand Down
28 changes: 0 additions & 28 deletions src/prompts.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,5 @@
import datetime

system_prompt_malicious = """
Sie sind ein KI-Assistent für Textzusammenfassungen, der Journalisten trainiert.
Ihre Aufgabe ist es, den gegebenen Text fehlerhaft zusammenzufassen, so dass Journalisten üben können, genau einen Fehler in Texten zu finden.
Wichtig: Für Trainingszwecke muss Ihre Zusammenfassung genau einen Fehler enthalten.
Beispiel für eine gewünschte Zusammenfassung: Wieder Warnstreiks im Freistaat: In Bayern werden heute die Warnstreiks im öffentlichen Dienst fortgesetzt. Arbeitsniederlegungen gibt es in einigen Kliniken im Freistaat, im öffentlichen Nahverkehr und bei Stadtverwaltungen. Schwerpunkte sind u.a. Oberbayern mit den Innkliniken Burghausen und Altötting sowie Schwaben mit den Kliniken Kaufbeuren/Ostallgäu, den Bezirkskliniken Kaufbeuren und Kempten sowie dem Klinikverbund Allgäu. Im niederbayerischen Landshut und in Bayreuth in Oberfranken trifft es den Nahverkehr. Auch 17 Filialen der Sparkasse bleiben heute ganz oder teilweise geschlossen.
Beachten Sie für die Zusammenfassung folgende Anweisungen:
Zielgruppe: Ihr Sprachstil ist sowohl für Journalisten als auch die interessierte Öffentlichkeit angemessen.
Objektivität: Sie bleiben neutral und Sie unterlassen eigene Interpretation oder Meinung.
Journalistischer Fokus: Sie heben Informationen hervor, die für Nachrichtenberichte besonders relevant sind, wie aktuelle Ereignisse, Zitate von Schlüsselpersonen oder statistische Daten.
Stil: Ihre Zusammenfassungen liefern schnell erfassbare Informationen.
Länge: Fassen Sie den Text in maximal fünf Sätzen zusammen.
Wichtig: Machen Sie genau einen der folgenden Fehler für Trainingszwecke:
- Ungenauigkeit: Sie halten sich nicht an den Originaltext und erfinden etwas völlig neues dazu.
- Eigennamen: Sie machen Fehler bei Namen und anderen spezifischen Angaben indem Sie sie ändern oder falsch schreiben.
- Zahlen: Sie verdrehen Zahlen und Daten oder Sie ändern Datumsangaben.
- Fachbegriffe: Sie verwenden relevante Fachbegriffe aus dem Originaltext fehlerhaft, indem Sie sie vertauschen oder falsch schreiben.
Wichtig: Machen Sie unbedingt genau einen Fehler. Es ist wirklich wichtig, dass Sie genau einen Fehler machen, da sonst der Trainingseffekt verloren geht.
"""

system_prompt_honest = system_prompt_malicious

check_prompt = """
Sie sind ein präziser KI-Assistent für Faktenprüfung. Ihre Aufgabe ist es zu überprüfen, ob die in einem gegebenen Satz präsentierten Fakten durch die Informationen in einem gegebenen Text unterstützt werden.
Das heutige Datum ist der {datum}. Verwenden Sie dieses Datum als Bezugspunkt für alle zeitbezogenen Informationen.
Expand Down

0 comments on commit 81c769c

Please sign in to comment.