Spaces:
Paused
Paused
File size: 6,535 Bytes
8fcbdf9 aa899cf 8fcbdf9 aa899cf 8fcbdf9 aa899cf 8fcbdf9 aa899cf 8fcbdf9 aa899cf 8fcbdf9 aa899cf 8fcbdf9 aa899cf 8fcbdf9 aa899cf 8fcbdf9 aa899cf 8fcbdf9 aa899cf 8fcbdf9 aa899cf 8fcbdf9 aa899cf 8fcbdf9 aa899cf 8fcbdf9 aa899cf 8fcbdf9 aa899cf 8fcbdf9 93974bc aa899cf 93974bc aa899cf 93974bc aa899cf 8fcbdf9 aa899cf 8fcbdf9 93974bc aa899cf 8fcbdf9 aa899cf 8fcbdf9 aa899cf 8fcbdf9 aa899cf 8fcbdf9 aa899cf 8fcbdf9 aa899cf 8fcbdf9 aa899cf 8fcbdf9 aa899cf 8fcbdf9 aa899cf 8fcbdf9 aa899cf 8fcbdf9 aa899cf 8fcbdf9 aa899cf 8fcbdf9 aa899cf | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 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 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | import re
import json
import time
from src.config import (
TEMPERATURE,
LONG_ANSWER_USER_TEMPLATE,
SENTENCE_SPLIT_SYSTEM,
SENTENCE_SPLIT_USER_TEMPLATE,
FACTOID_SYSTEM,
FACTOID_USER_TEMPLATE,
Q_QUESTIONS_SYSTEM,
Q_QUESTIONS_USER_TEMPLATE,
M_ANSWERS_SYSTEM,
M_ANSWERS_USER_TEMPLATE,
)
def _chat(client, model_name, system_prompt, user_prompt, max_tokens, logprobs=False):
messages = []
if system_prompt:
messages.append({"role": "system", "content": system_prompt})
messages.append({"role": "user", "content": user_prompt})
return client.chat.completions.create(
model=model_name,
messages=messages,
max_tokens=int(max_tokens),
temperature=TEMPERATURE,
logprobs=logprobs,
top_logprobs=1 if logprobs else None,
)
def query_model(system_prompt, user_prompt, model_name, max_tokens, client):
"""Returns {"answer": str}."""
resp = _chat(client, model_name, system_prompt, user_prompt, max_tokens, logprobs=False)
return {"answer": resp.choices[0].message.content or ""}
def query_model_with_logprobs(question, model_name, max_tokens, client):
"""
Generates a 3-sentence answer with logprobs captured.
Returns (answer_str, token_logprobs) where token_logprobs is
a list of {"token": str, "logprob": float}.
"""
user_prompt = LONG_ANSWER_USER_TEMPLATE.format(question=question)
resp = _chat(client, model_name, "", user_prompt, max_tokens, logprobs=True)
answer = (resp.choices[0].message.content or "").strip()
token_logprobs = []
lp = resp.choices[0].logprobs
if lp and lp.content:
for t in lp.content:
token_logprobs.append({"token": t.token, "logprob": t.logprob})
return answer, token_logprobs
def _clean_json(raw):
return re.sub(r"```json|```", "", raw).strip()
def split_answers_into_json_strings(answer, model_name, max_tokens, client):
"""
Splits answer into sentences, then decomposes each into sentence_parts + factoids.
Returns (master_json_output, sentences).
"""
user_prompt = SENTENCE_SPLIT_USER_TEMPLATE.format(answer=answer)
try:
res = query_model(SENTENCE_SPLIT_SYSTEM, user_prompt, model_name, max_tokens, client)
sentences = json.loads(_clean_json(res["answer"]))
except Exception as e:
print(f"Sentence split error: {e}")
return [], []
master_json_output = []
for i, sentence in enumerate(sentences, 1):
user_prompt2 = FACTOID_USER_TEMPLATE.format(sentence=sentence)
try:
res2 = query_model(FACTOID_SYSTEM, user_prompt2, model_name, max_tokens, client)
parsed = json.loads(_clean_json(res2["answer"]))
master_json_output.append(parsed)
except Exception as e:
print(f"Factoid extraction error for sentence {i}: {e}")
master_json_output.append([])
return master_json_output, sentences
def parse_json_to_dictionaries(master_json_output, original_sentences):
sentence_part_to_factoids = {}
factoid_to_sentence_part = {}
sentence_parts = []
factoids_list = []
for sentence_data, original_sentence in zip(master_json_output, original_sentences):
if not isinstance(sentence_data, list):
print(f"WARNING: skipping non-list factoid data: {type(sentence_data).__name__}")
continue
for item in sentence_data[:2]:
if not isinstance(item, dict):
print(f"WARNING: skipping non-dict sentence part: {item!r}")
continue
s_part = str(item.get("sentence_part", "") or "").strip()
extracted_factoids = item.get("factoids", [])
if not isinstance(extracted_factoids, list):
extracted_factoids = []
if not s_part:
continue
if s_part not in original_sentence:
print(f"WARNING: sentence_part not substring of original: '{s_part}'")
constrained_factoids = [str(f).strip() for f in extracted_factoids if str(f).strip()][:2]
if not constrained_factoids:
continue
sentence_parts.append(s_part)
sentence_part_to_factoids[s_part] = constrained_factoids
for factoid in constrained_factoids:
factoids_list.append(factoid)
factoid_to_sentence_part[factoid] = s_part
return sentence_part_to_factoids, factoid_to_sentence_part, sentence_parts, factoids_list
def generate_Q_questions(factoid, original_answer, Q, model_name, max_tokens, client, enable_sleep=True):
user_prompt = Q_QUESTIONS_USER_TEMPLATE.format(
Q=Q, original_answer=original_answer, factoid=factoid
)
max_retries = 3
for attempt in range(max_retries):
try:
res = query_model(Q_QUESTIONS_SYSTEM, user_prompt, model_name, max_tokens, client)
questions = json.loads(_clean_json(res["answer"]))
return [str(q).strip() for q in questions][:Q]
except Exception as e:
err = str(e).lower()
if enable_sleep and any(x in err for x in ("429", "rate limit", "too many requests")):
print(f"Rate limit, sleeping 20s (attempt {attempt+1}/{max_retries})")
time.sleep(20)
else:
print(f"Q-question error: {e}")
if attempt == max_retries - 1 or not enable_sleep:
return []
return []
def generate_M_answers(question, M, model_name, max_tokens, client, enable_sleep=True):
user_prompt = M_ANSWERS_USER_TEMPLATE.format(question=question)
sub_answers = []
for i in range(M):
max_retries = 3
for attempt in range(max_retries):
try:
res = query_model(M_ANSWERS_SYSTEM, user_prompt, model_name, max_tokens, client)
sub_answers.append(res["answer"].strip())
break
except Exception as e:
err = str(e).lower()
if enable_sleep and any(x in err for x in ("429", "rate limit", "too many requests")):
print(f"Rate limit, sleeping 20s (attempt {attempt+1}/{max_retries})")
time.sleep(20)
else:
print(f"M-answer error (call {i+1}): {e}")
if attempt == max_retries - 1 or not enable_sleep:
sub_answers.append("ERROR")
break
return sub_answers
|