from typing import Optional from transformers import AutoTokenizer import re import json BASE_MODEL = "meta-llama/Meta-Llama-3.1-8B" MIN_TOKENS = 150 # Any less than this, and we don't have enough useful content MAX_TOKENS = 160 # Truncate after this many tokens. Then after adding in prompt text, we will get to around 180 tokens MIN_CHARS = 300 CEILING_CHARS = MAX_TOKENS * 7 class Item: """ An Item is a cleaned, curated datapoint of a Product with a Price """ tokenizer = AutoTokenizer.from_pretrained(BASE_MODEL, trust_remote_code=True) PREFIX = "Result is " QUESTION = "How would you classify this sensor data - normal or anomalous?" REMOVALS = ['"event": "car_opened"'] result: str category: str token_count: int = 0 details: Optional[str] prompt: Optional[str] = None include = False def __init__(self, data, result): self.result = result self.parse(data) def scrub(self, stuff): """ Clean up the provided text by removing unnecessary characters and whitespace """ return stuff def parse(self, data): """ Parse this datapoint and if it fits within the allowed Token range, then set include to True """ contents = json.dumps(data['input']) if contents: contents += '\n' self.details = contents if len(contents) > MIN_CHARS: contents = contents[:CEILING_CHARS] text = f"{self.scrub(contents)}" tokens = self.tokenizer.encode(text, add_special_tokens=False) if len(tokens) > MIN_TOKENS: tokens = tokens[:MAX_TOKENS] text = self.tokenizer.decode(tokens) self.make_prompt(text) self.include = True def make_prompt(self, text): """ Set the prompt instance variable to be a prompt appropriate for training """ self.prompt = f"{self.QUESTION}\n\n{text}\n\n" self.prompt += f"{self.PREFIX}{self.result}" self.token_count = len(self.tokenizer.encode(self.prompt, add_special_tokens=False)) def test_prompt(self): """ Return a prompt suitable for testing, with the actual price removed """ return self.prompt.split(self.PREFIX)[0] + self.PREFIX def __repr__(self): """ Return a String version of this Item """ return f"<${self.result}>"