mirror of
https://github.com/hanzoai/open-instruct.git
synced 2026-10-30 18:26:32 +00:00
* move rejection sampling within its own directory * move rejection sampling within its own directory * add api-based models to generating completions * debug * debug * debug * debug * debug * do not apply tokenization with chat template * change the tokenizer * change the tokenizer * fix template * fix arg issue * add mode to arg * add mode to arg * change the skill * remove main from api_generate.py * modify template chat * modify template chat * return only text * return only text * return only text * fix dict * fix dict * fix dict * fix dict * fix dict * fix dict * add LM as a scorer * add LM as a scorer * add LM as a scorer * add LM as a scorer * change the name of the model * fix rank bug * process score * process score * edit the template * extract score * compute scores for reference responses * compute scores for reference responses * add tqdm * add tqdm * fix score bug * fix item bug * fix item bug * fixed code style * fixed code style * .idea added to .gitignore * .idea dir removed * remove unused llm_as_judge file * Update rejection_sampling.md * fix the path to rejection sampling files * update readme * remove unused args * use args * remove args * fix chatgpt completion * fix chatgpt completion * fix chatgpt completion * fix bug * fix format conversation * fix minor bug * fix minor bug * fix minor bug * fix minor bug * fix parsing response * test judgment * update format * update format * debug * debug * debug * fix * format fixed * format fixed * fix bug * fix bug * fix bug * fix bug * add comment * update n * duplicate * generate n completions per prompt * generate n completions per prompt * generate n completions per prompt * generate n completions per prompt * generate n completions per prompt * generate n completions per prompt * generate n completions per prompt * generate n completions per prompt * generate n completions per prompt * generate n completions per prompt * debug * improve response * improve response * completions n * completions n * completions n * remove debug * fix outputs structure * fix outputs structure * fix outputs structure * fix outputs structure * fix outputs structure * push a new branch * black * use consistent naming * add debugging output * push changes * push changes * update docs * filter out prompts which are beyond the model's max token length * quick change * quick fix on bash script * quick fix --------- Co-authored-by: Costa Huang <[email protected]>
96 lines
3.7 KiB
Python
96 lines
3.7 KiB
Python
# main.py
|
|
|
|
import asyncio
|
|
import re
|
|
from dataclasses import dataclass
|
|
from typing import List, Optional
|
|
|
|
import numpy as np
|
|
from openai import AsyncOpenAI
|
|
from tqdm.asyncio import tqdm
|
|
|
|
from open_instruct.rejection_sampling.prompt_templates import (
|
|
get_generation_template,
|
|
get_judgment_template,
|
|
)
|
|
|
|
|
|
@dataclass
|
|
class LLMGenerationConfig:
|
|
num_completions: int = 64
|
|
model: str = "gpt-3.5-turbo-0125"
|
|
max_parallel_requests: Optional[int] = None
|
|
|
|
def __post_init__(self):
|
|
if "gpt-3.5" in self.model:
|
|
self.max_parallel_requests = 11
|
|
elif "gpt-4" in self.model:
|
|
self.max_parallel_requests = 13
|
|
|
|
|
|
@dataclass
|
|
class Args:
|
|
output_path: Optional[str] = None
|
|
num_trials: int = 1
|
|
|
|
|
|
class LLMProcessor:
|
|
def __init__(self, config: LLMGenerationConfig):
|
|
self.config = config
|
|
self.async_client = AsyncOpenAI()
|
|
|
|
async def process_text(self, data: dict, i: int, limiter: asyncio.Semaphore, args: Args, gen_args: Args):
|
|
if args.mode == "generation":
|
|
template = get_generation_template(args.skill)
|
|
text = template.format(prompt=data)
|
|
elif args.mode == "judgement": # judgment mode
|
|
template = get_judgment_template(args.skill)
|
|
text = template.format(prompt=data["prompt"], response=data["response"])
|
|
else:
|
|
raise ValueError(f"Invalid mode: {args.mode}")
|
|
|
|
async with limiter:
|
|
while True:
|
|
try:
|
|
response = await self.async_client.chat.completions.create(
|
|
model=self.config.model,
|
|
messages=[
|
|
{"role": "system", "content": "You are a helpful assistant."},
|
|
{"role": "user", "content": text},
|
|
],
|
|
n=gen_args.num_completions, # Request multiple completions
|
|
temperature=gen_args.temperature, # Sampling temperature
|
|
max_tokens=gen_args.response_length, # Maximum tokens in the response
|
|
top_p=gen_args.top_p, # Top-P (nucleus) sampling
|
|
stop=None, # Add stopping criteria if needed
|
|
)
|
|
# Collect all completions if `n > 1`
|
|
completions = [choice.message.content for choice in response.choices]
|
|
if args.mode == "generation":
|
|
response = completions
|
|
elif args.mode == "judgement":
|
|
# If in judgment mode, process the completions (for example, extracting scores)
|
|
scores = []
|
|
for completion in completions:
|
|
match = re.search(r"Total score:\s*(\d+)", completion)
|
|
if match:
|
|
score = int(match.group(1))
|
|
else:
|
|
score = -1
|
|
scores.append(score)
|
|
response = np.mean(scores)
|
|
else:
|
|
raise ValueError(f"Invalid mode: {args.mode}")
|
|
break
|
|
except Exception as e:
|
|
print(f"Error in {i}: {e}")
|
|
await asyncio.sleep(30)
|
|
|
|
return response
|
|
|
|
async def process_batch(self, data_list: List[dict], args: Args, gen_args: Args):
|
|
limiter = asyncio.Semaphore(self.config.max_parallel_requests)
|
|
tasks = [self.process_text(data, i, limiter, args, gen_args) for i, data in enumerate(data_list)]
|
|
# Use tqdm to track progress
|
|
return await tqdm.gather(*tasks, total=len(tasks), desc="Processing Batch")
|