{ "cells": [ { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# Testing" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "```source: this key separates the various keys found in the table in Sources. Here's the set of sources with their corresponding value name:```\n", "```\n", "'https://aipulse.org'\n", "'ebook'\n", "'https://qualiacomputing.com'\n", "'alignment forum'\n", "'lesswrong'\n", "'manual'\n", "'arxiv'\n", "'https://deepmindsafetyresearch.medium.com/'\n", "'waitbutwhy.com'\n", "'GitHub'\n", "'https://aiimpacts.org'\n", "'arbital.com'\n", "'carado.moe'\n", "'nonarxiv_papers'\n", "'https://vkrakovna.wordpress.com'\n", "'https://jsteinhardt.wordpress.com'\n", "'audio-transcripts'\n", "'https://intelligence.org'\n", "'youtube'\n", "'reports'\n", "'https://aisafety.camp'\n", "'curriculum'\n", "'https://www.yudkowsky.net'\n", "'distill'\n", "```\n", "\n", "```...and this is how the arxiv papers look like:```\n", "\n", "```\n", "{\n", " \"source\": \"arxiv\", # where the dataset comes from\n", " \"source_type\": \"latex\", # the type of file the data was original in\n", " \"converted_with\": \"pandoc\", # which tool we used to convert the data in .md format\n", " \"paper_version\": paper_id,\n", " \"title\": title,\n", " \"authors\": [str(x) for x in authors], # list of authors\n", " \"date_published\": date_published,\n", " \"data_last_modified\": data_last_modified,\n", " \"url\": url,\n", " \"abstract\": abstract,\n", " \"author_comment\": author_comment,\n", " \"journal_ref\": journal_ref,\n", " \"doi\": doi,\n", " \"primary_category\": primary_category,\n", " \"categories\": categories,\n", " \"citation_level\": citation_level, # (0 = curated alignment papers, 1 = citation of curated papers, 2 = citation of citation, etc.)\n", " \"alignment_text\": is_alignment_text, # 'pos' is maunally labeled as an alignment paper, 'unlabeled' if unlabeled\n", " \"confidence_score\": confidence_scores, # this is a confidence score obtained by using the SPECTER model to classify papers to add to the dataset\n", " \"main_tex_filename\": \"main.tex\", # the main latex file needed to convert the paper\n", " \"text\": \"lots of text\", # this is where you will grab the text contents of each entry in the dataset (in .md format)\n", " \"bibliography_bbl\": \"string of bbl\",\n", " \"bibliography_bib\": \"string of bib\", # more common to have bib than bbl\n", "}\n", "```" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Useful links:\n", "\n", "- Semantic Search OpenAI Cookbook: https://github.com/openai/openai-cookbook/blob/main/examples/Semantic_text_search_using_embeddings.ipynb\n", "\n", "- Question-Answering OpenAI Cookbook: https://github.com/openai/openai-cookbook/blob/main/examples/Question_answering_using_embeddings.ipynb\n", "\n", "- Pinecone: https://app.pinecone.io\n", "\n", "- Retrieval Enhanced Generative Question Answering with Pinecone: https://github.com/openai/openai-cookbook/blob/main/examples/vector_databases/pinecone/Gen_QA.ipynb\n", "\n", "- Moderation: https://platform.openai.com/docs/guides/moderation/quickstart\n", "\n", "- 5k Bounty: https://www.lesswrong.com/posts/SLRLuiuDykfTdmesK/speed-running-everyone-through-the-bad-alignement-bingo\n", "\n", "- Handling rate-limits Cookbook: https://github.com/openai/openai-cookbook/blob/main/examples/How_to_handle_rate_limits.ipynb" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Imports" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import jsonlines\n", "import numpy as np\n", "from typing import List, Dict, Tuple, DefaultDict, Any\n", "import re\n", "import time\n", "import random\n", "import pickle\n", "import openai\n", "import concurrent.futures\n", "from tenacity import (\n", " retry,\n", " stop_after_attempt,\n", " wait_random_exponential,\n", ") # for exponential backoff\n", "import tiktoken\n", "\n", "import config\n", "from pathlib import Path\n", "from collections import defaultdict" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# FROM https://stackoverflow.com/a/31505798/16185542\n", "# -*- coding: utf-8 -*-\n", "alphabets= \"([A-Za-z])\"\n", "prefixes = \"(Mr|St|Mrs|Ms|Dr)[.]\"\n", "suffixes = \"(Inc|Ltd|Jr|Sr|Co)\"\n", "starters = \"(Mr|Mrs|Ms|Dr|Prof|Capt|Cpt|Lt|He\\s|She\\s|It\\s|They\\s|Their\\s|Our\\s|We\\s|But\\s|However\\s|That\\s|This\\s|Wherever)\"\n", "acronyms = \"([A-Z][.][A-Z][.](?:[A-Z][.])?)\"\n", "websites = \"[.](com|net|org|io|gov|edu|me)\"\n", "digits = \"([0-9])\"\n", "\n", "def split_into_sentences(text):\n", " text = \" \" + text + \" \"\n", " text = text.replace(\"\\n\",\" \")\n", " text = text.replace(\"?!\", \"?\")\n", " text = re.sub(prefixes,\"\\\\1\",text)\n", " text = re.sub(websites,\"\\\\1\",text)\n", " text = re.sub(digits + \"[.]\" + digits,\"\\\\1\\\\2\",text)\n", " if \"...\" in text: text = text.replace(\"...\",\"\")\n", " if \"Ph.D\" in text: text = text.replace(\"Ph.D.\",\"PhD\")\n", " text = re.sub(\"\\s\" + alphabets + \"[.] \",\" \\\\1 \",text)\n", " text = re.sub(acronyms+\" \"+starters,\"\\\\1 \\\\2\",text)\n", " text = re.sub(alphabets + \"[.]\" + alphabets + \"[.]\" + alphabets + \"[.]\",\"\\\\1\\\\2\\\\3\",text)\n", " text = re.sub(alphabets + \"[.]\" + alphabets + \"[.]\",\"\\\\1\\\\2\",text)\n", " text = re.sub(\" \"+suffixes+\"[.] \"+starters,\" \\\\1 \\\\2\",text)\n", " text = re.sub(\" \"+suffixes+\"[.]\",\" \\\\1\",text)\n", " text = re.sub(\" \" + alphabets + \"[.]\",\" \\\\1\",text)\n", " if \"”\" in text: text = text.replace(\".”\",\"”.\")\n", " if \"\\\"\" in text: text = text.replace(\".\\\"\",\"\\\".\")\n", " if \"!\" in text: text = text.replace(\"!\\\"\",\"\\\"!\")\n", " if \"?\" in text: text = text.replace(\"?\\\"\",\"\\\"?\")\n", " text = text.replace(\".\",\".\")\n", " text = text.replace(\"?\",\"?\")\n", " text = text.replace(\"!\",\"!\")\n", " text = text.replace(\"\",\".\")\n", "\n", " sentences = text.split(\"\")\n", " sentences = sentences[:-1]\n", " sentences = [s.strip() for s in sentences]\n", " \n", " if sentences == []:\n", " sentences = [text.strip()]\n", " return sentences\n", "\n", "\n", "class TokenSplitter:\n", " \"\"\"splits text into blocks of tokens according to chatgpt's tokenizer\"\"\"\n", " def __init__(self, min_tokens: int = 500, max_tokens: int = 750):\n", " self.encoding = tiktoken.get_encoding(\"cl100k_base\")\n", " self.min_tokens = min_tokens\n", " self.max_tokens = max_tokens\n", " self.blocks = []\n", " self.signature = \"{url, title, author} unknown\"\n", " \n", "\n", "\n", " def _text_splitter(self, text: str) -> List[str]:\n", " \"\"\"splits text into blocks of tokens according to chatgpt's tokenizer\"\"\"\n", " # Do not call this function outside of split() \n", " \n", " enc = self.encoding.encode # takes a string and returns a list of ints (tokens)\n", " dec = self.encoding.decode # takes a list of ints (tokens) and returns a string\n", " tok_len = lambda x: len(enc(x)) # length of a string in tokens\n", "\n", " max_tokens = self.max_tokens - tok_len(self.signature) - 10 # 10 to be safe\n", " assert max_tokens > 0, \"max_tokens is too small for the signature\"\n", " \n", " min_tokens = self.min_tokens - tok_len(self.signature) - 10 # 10 to be safe\n", " assert min_tokens > 0, \"min_tokens is too small for the signature\"\n", "\n", " current_block = \"\"\n", " paragraphs = text.split(\"\\n\\n\")\n", " for paragraph in paragraphs:\n", " sentences = split_into_sentences(paragraph)\n", " if current_block != \"\":\n", " current_block += \"\\n\\n\"\n", "\n", " for sentence in sentences:\n", " potential_new_block = current_block + \" \" + sentence\n", " \n", " if tok_len(potential_new_block) <= max_tokens:\n", " current_block = potential_new_block\n", " \n", " else:\n", " self.blocks.append(current_block)\n", " if tok_len(sentence) < max_tokens:\n", " current_block = sentence\n", " else:\n", " self.blocks.append(dec(enc(sentence)[:max_tokens]))\n", " current_block = \"\"\n", " \n", " if tok_len(current_block) > min_tokens:\n", " self.blocks.append(current_block)\n", " current_block = \"\"\n", "\n", " if current_block != \"\":\n", " if len(self.blocks) == 0:\n", " self.blocks.append(current_block)\n", " return\n", " latest_block = self.blocks[-1]\n", " len_cur_block = tok_len(current_block)\n", " latest_plus_current = latest_block + current_block\n", "\n", " if len_cur_block > min_tokens:\n", " self.blocks.append(current_block)\n", " \n", " else:\n", " #select the last self.max_tokens tokens from the latest block\n", " last_block = dec(enc(latest_plus_current)[-max_tokens:])\n", " self.blocks.append(last_block)\n", "\n", " \n", " \n", " def split(self, text: str, signature: str) -> List[str]:\n", " self.signature = signature\n", " self._text_splitter(text)\n", " blocks = self.blocks\n", " self.blocks = []\n", " self.signature = \"{url, title, author} unknown\"\n", " \n", " # check all block elements are strings\n", " assert all([isinstance(block, str) for block in blocks]), \"block elements are not strings\"\n", "\n", " output = [f\"{block}\\n - {signature}\" for block in blocks]\n", " #check all output elements are strings\n", " assert all([isinstance(block, str) for block in output]), \"output elements are not strings\"\n", "\n", " return output" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Constants" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "LEN_EMBEDDINGS = 1536\n", "\n", "COMPLETIONS_MODEL = \"gpt-3.5-turbo\"\n", "EMBEDDING_MODEL = \"text-embedding-ada-002\"\n", "\n", "openai.api_key = config.OPENAI_API_KEY\n", "\n", "\n", "project_path = Path.cwd().parent # .cwd() returns the current working directory, \n", "# but in a notebook it is the directory of the notebook. So we need to go up two levels.\n", "PATH_TO_DATA = project_path / \"src\" / \"data\" / \"alignment_texts.jsonl\" # Path to the dataset .jsonl file.\n", "PATH_TO_EMBEDDINGS = project_path / \"src\" / \"data\" / \"embeddings.npy\" # Path to the saved embeddings (.npy) file.\n", "PATH_TO_DATASET = project_path / \"src\" / \"data\" / \"dataset.pkl\" # Path to the saved dataset (.pkl) file." ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Helpers" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "class MissingDataException(Exception):\n", " pass" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Dataset Class" ] }, { "cell_type": "code", "execution_count": 129, "metadata": {}, "outputs": [], "source": [ "error_count_dict = {\n", " \"Entry has no source.\": 0,\n", " \"Entry has no title.\": 0,\n", " \"Entry has no text.\": 0,\n", " \"Entry has no URL.\": 0,\n", " \"Entry has wrong citation level.\": 0\n", "}\n", "\n", "class Dataset:\n", " def __init__(self,\n", " jsonl_data_path: str, # Path to the dataset .jsonl file.\n", " custom_sources: List[str] = None, # List of sources to include, like \"alignment forum\", \"lesswrong\", \"arxiv\",etc.\n", " rate_limit_per_minute: int = 3_500, # Rate limit for the OpenAI API.\n", " min_tokens_per_block: int = 400, # Minimum number of tokens per block.\n", " max_tokens_per_block: int = 600, # Maximum number of tokens per block.\n", " fraction_of_articles_to_use: float = 1.0, # Fraction of articles to use. If 1.0, use all articles.\n", " ):\n", " self.jsonl_data_path = jsonl_data_path\n", " self.custom_sources = custom_sources\n", " self.rate_limit_per_minute = rate_limit_per_minute\n", " self.delay_in_seconds = 60.0 / self.rate_limit_per_minute\n", " self.fraction_of_articles_to_use = fraction_of_articles_to_use\n", " \n", " self.min_tokens_per_block = min_tokens_per_block # for the text splitter\n", " self.max_tokens_per_block = max_tokens_per_block # for the text splitter\n", " \n", " self.metadata: List[Tuple[str]] = [] # List of tuples, each containing the title of an article, its URL, and text. E.g.: [('title', 'url', 'text'), ...]\n", " self.embedding_strings: List[str] = [] # List of strings, each being a few paragraphs from a single article (not exceeding 1000 words).\n", " \n", " self.articles_count: DefaultDict[str, int] = defaultdict(int) # Number of articles per source. E.g.: {'source1': 10, 'source2': 20, 'total': 30}\n", "\n", " if self.custom_sources is not None:\n", " for source in self.custom_sources:\n", " self.articles_count[source] = 0\n", " self.total_articles_count = 0\n", " \n", " self.total_char_count = 0\n", " self.total_word_count = 0\n", " self.total_sentence_count = 0\n", " self.total_block_count = 0\n", " \n", " self.sources_so_far: List[str] = []\n", " self.info_types: Dict[str, List[str]] = {}\n", " \n", " def extract_info_from_article(self, article: Dict[str, Any]) -> Tuple[str]:\n", " \"\"\"\n", " This function extracts the title, author, date, URL, tags, and text from an article.\n", " \n", " Args:\n", " article (Dict[str, Any]): a dictionary containing the article's text and metadata.\n", "\n", " Returns:\n", " Tuple[str]: a tuple containing the title, author, date, URL, tags, and text of the article.\n", " \"\"\"\n", " title = None\n", " author = None\n", " date_published = None\n", " url = None\n", " tags = None\n", " text = None\n", " \n", " # Get title\n", " if 'title' in article and 'book_title' in article and article['title']: title = article['title']\n", " elif 'book_title' in article and 'title' not in article and article['book_title']: \n", " title = article['book_title']\n", " if title[-1] == '\\n': title = title[:-1]\n", " elif 'title' in article and article['title']: \n", " title = article['title']\n", " if title[-1] == '\\n': title = title[:-1]\n", " else: title = None\n", "\n", " # Get author\n", " if 'author' in article and 'authors' in article and article['author']: author = article['author']\n", " elif 'authors' in article and article['authors']: author = article['authors']\n", " elif 'author' in article and article['author']: author = article['author']\n", " else: author = None\n", "\n", " # Get date published\n", " if 'date_published' in article and article['date_published'] and len(article['date_published']) >= 10: date_published = article['date_published'][:10]\n", " elif 'published' in article and article['published'] and len(article['published']) >= 16: date_published = article['published'][:16]\n", " else: date_published = None\n", " \n", " # Get URL\n", " if 'link' in article and article['link']: url = article['link']\n", " elif 'url' in article and article['url']: url = article['url']\n", " elif 'doi' in article and article['doi']: url = article['doi']\n", " else: url = None\n", " \n", " # Get tags\n", " if 'tags' in article and article['tags']:\n", " if type(article['tags']) == list: tags = ', '.join([val['term'] for val in article['tags']])\n", " elif type(article['tags']) == str: tags = article['tags']\n", " else: tags = None\n", " \n", " # Get text\n", " if 'text' in article and article['text']: text = article['text']\n", " else:\n", " raise MissingDataException(f\"Entry has no text.\")\n", "\n", " return (title, author, date_published, url, tags, text)\n", " \n", " def get_alignment_texts(self):\n", " text_splitter = TokenSplitter(self.min_tokens_per_block, self.max_tokens_per_block)\n", " with jsonlines.open(self.jsonl_data_path, \"r\") as reader:\n", " for entry in reader:\n", " try:\n", " if 'source' not in entry: \n", " if 'url' in entry and entry['url'] == \"https://www.cold-takes.com/\": \n", " entry[\"source\"] = \"Cold Takes\"\n", " elif 'question' in entry and 'answer' in entry: \n", " entry[\"source\"] = \"printouts\"\n", " continue # for now, skip printouts\n", " elif 'article_url' in entry and entry['article_url'] == \"https://www.gwern.net\":\n", " entry[\"source\"] = \"gwern.net\"\n", " elif 'url' in entry and entry['url'] == \"https://generative.ink/posts/\":\n", " entry[\"source\"] = \"generative.ink\"\n", " elif 'url' in entry and entry['url'][:24] == \"https://greaterwrong.com\":\n", " entry[\"source\"] = \"greaterwrong.com\"\n", " else:\n", " raise MissingDataException(\"Entry has no source.\")\n", " \n", " random_number = random.random()\n", " if random_number > self.fraction_of_articles_to_use:\n", " continue\n", " \n", " # if we specified custom sources, only include articles from those sources\n", " if (self.custom_sources is not None) and (entry['source'] not in self.custom_sources):\n", " continue\n", " self.articles_count[entry['source']] += 1\n", " self.total_articles_count += 1\n", " \n", " # Get title, author, date, URL, tags, and text\n", " title, author, date_published, url, tags, text = self.extract_info_from_article(entry)\n", " \n", " # Get signature\n", " signature = \"\"\n", " if title: signature += f\"Title: {title}, \"\n", " if author: signature += f\"Author: {author}, \"\n", " if date_published: signature += f\"Date published: {date_published}, \"\n", " if url: signature += f\"URL: {url}, \"\n", " # if tags: signature += f\"Tags: {tags}, \" # Temporary decision to not include tags in the signature\n", " if signature: signature = signature[:-2]\n", " \n", " # Add info to metadata and embedding strings\n", " self.metadata.append((title, author, date_published, url, tags, text))\n", " blocks = text_splitter.split(text, signature)\n", " self.embedding_strings.extend(blocks)\n", " \n", " # Update counts\n", " self.total_char_count += len(text)\n", " self.total_word_count += len(text.split())\n", " self.total_sentence_count += len(split_into_sentences(text))\n", " self.total_block_count += len(blocks)\n", " \n", " except MissingDataException as e:\n", " if str(e) not in error_count_dict:\n", " error_count_dict[str(e)] = 0\n", " error_count_dict[str(e)] += 1\n", "\n", " def get_embeddings(self):\n", " # Get an embedding for each text, with retries if necessary\n", " @retry(wait=wait_random_exponential(min=1, max=20), stop=stop_after_attempt(5))\n", " def get_embedding_at_index(text: str, i: int, delay_in_seconds: float = 0) -> np.ndarray:\n", " time.sleep(delay_in_seconds)\n", " embedding = openai.Embedding.create(\n", " model=EMBEDDING_MODEL, \n", " input=text\n", " )\n", " return i, embedding[\"data\"][0][\"embedding\"]\n", " \n", " start = time.time()\n", " self.embeddings = np.zeros((len(self.embedding_strings), LEN_EMBEDDINGS))\n", " \n", " with concurrent.futures.ThreadPoolExecutor() as executor:\n", " futures = [executor.submit(get_embedding_at_index, text, i) for i, text in enumerate(self.embedding_strings)]\n", " num_completed = 0\n", " for future in concurrent.futures.as_completed(futures):\n", " i, embedding = future.result()\n", " self.embeddings[i] = embedding\n", " num_completed += 1\n", " if num_completed % 50 == 0:\n", " print(f\"Completed {num_completed}/{len(self.embedding_strings)} embeddings in {time.time() - start:.2f} seconds.\")\n", " print(f\"Completed {num_completed}/{len(self.embedding_strings)} embeddings in {time.time() - start:.2f} seconds.\")\n", " \n", " def save_embeddings(self, path: str):\n", " np.save(path, self.embeddings)\n", " \n", " def load_embeddings(self, path: str):\n", " self.embeddings = np.load(path)\n", " \n", " def save_class(self, path: str):\n", " with open(path, 'wb') as f:\n", " pickle.dump(self, f)" ] }, { "cell_type": "code", "execution_count": 131, "metadata": {}, "outputs": [], "source": [ "# List of possible sources:\n", "all_sources = [\"https://aipulse.org\", \"ebook\", \"https://qualiacomputing.com\", \"alignment forum\", \"lesswrong\", \"manual\", \"arxiv\", \"https://deepmindsafetyresearch.medium.com\", \"waitbutwhy.com\", \"GitHub\", \"https://aiimpacts.org\", \"arbital.com\", \"carado.moe\", \"nonarxiv_papers\", \"https://vkrakovna.wordpress.com\", \"https://jsteinhardt.wordpress.com\", \"audio-transcripts\", \"https://intelligence.org\", \"youtube\", \"reports\", \"https://aisafety.camp\", \"curriculum\", \"https://www.yudkowsky.net\", \"distill\",\n", " \"Cold Takes\", \"printouts\", \"gwern.net\", \"generative.ink\", \"greaterwrong.com\"] # These sources do not have a source field in the .jsonl file\n", "\n", "# List of sources we are using for the test run:\n", "custom_sources = [\n", " \"https://aipulse.org\", \n", " # \"ebook\", \n", " # \"https://qualiacomputing.com\", \n", " # \"alignment forum\", \n", " # \"lesswrong\", \n", " \"manual\", \n", " # \"arxiv\", \n", " # \"https://deepmindsafetyresearch.medium.com\", \n", " \"waitbutwhy.com\", \n", " # \"GitHub\", \n", " # \"https://aiimpacts.org\", \n", " # \"arbital.com\", \n", " # \"carado.moe\", \n", " # \"nonarxiv_papers\", \n", " \"https://vkrakovna.wordpress.com\", \n", " \"https://jsteinhardt.wordpress.com\", \n", " # \"audio-transcripts\", \n", " # \"https://intelligence.org\", \n", " # \"youtube\", \n", " # \"reports\", \n", " \"https://aisafety.camp\", \n", " \"curriculum\", \n", " \"https://www.yudkowsky.net\", \n", " # \"distill\",\n", " # \"Cold Takes\",\n", " # \"printouts\",\n", " # \"gwern.net\",\n", " # \"generative.ink\",\n", " # \"greaterwrong.com\"\n", "]\n", "\n", "dataset = Dataset(\n", " jsonl_data_path=PATH_TO_DATA.resolve(), \n", " custom_sources=custom_sources, \n", " rate_limit_per_minute=3500, \n", " min_tokens_per_block=200, max_tokens_per_block=350, \n", " # fraction_of_articles_to_use=1/2000\n", ")\n", "dataset.get_alignment_texts()\n", "\n", "\n", "# with open(PATH_TO_DATASET.resolve(), 'rb') as f:\n", "# dataset = pickle.load(f)" ] }, { "cell_type": "code", "execution_count": 154, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Title: Model Mis-specification and Inverse Reinforcement Learning\n", "Author: jsteinhardt\n", "Date published: Tue, 07 Feb 2017\n", "URL: https://jsteinhardt.wordpress.com/2017/02/07/model-mis-specification-and-inverse-reinforcement-learning/\n", "Tags: Locomotion\n", "Text: Model Mis-specification and Inverse Reinforcement Learning\n", "\n", "In my previous post, “Latent Variables and Model Mis-specification”, I argued that while machine learning is good at optimizing accuracy on observed signals, it has less to say about correctly inferring the values for unobserved variables in a model. In this post I’d like to focus in on a specific context for this: inverse reinforcement learning (Ng et al. 2000, Abeel et al. 2004, Ziebart et al. 2008, Ho et al 2016), where one observes the actions of an agent and wants to infer the preferences and beliefs that led to those actions. For this post, I am pleased to be joined by Owain Evans, who is an active researcher in this area and has co-authored an online book about building models of agents (see here in particular for a tutorial on inverse reinforcement learning and inverse planning).\n", "Owain and I are particularly interested in inverse reinforcement learning (IRL) because it has been proposed (most notably by Stuart Russell) as a method for learning human values in the context of AI safety; among other things, this would eventually involve learning and correctly implementing human values by artificial agents that are much more powerful, and act with much broader scope, than any humans alive today. While we think that overall IRL is a promising route to consider, we believe that there are also a number of non-obvious pitfalls related to performing IRL with a mis-specified model. The role of IRL in AI safety is to infer human values, which are represented by a reward function or utility function. But crucially, human values (or human reward functions) are never directly observed.\n", "Below, we elaborate on these issues. We hope that by being more aware of these issues, researchers working on inverse reinforcement learning can anticipate and address the resulting failure modes. In addition, we think that considering issues caused by model mis-specification in a particular concrete context can better elucidate the general issues pointed to in the previous post on model mis-specification.\n", "Specific Pitfalls for Inverse Reinforcement Learning\n", "\n", "In “Latent Variables and Model Mis-specification”, Jacob talked about model mis-specification, where the “true” model does not lie in the model family being considered. We encourage readers to read that post first, though we’ve also tried to make the below readable independently.\n", "In the context of inverse reinforcement learning, one can see some specific problems that might arise due to model mis-specification. For instance, the following are things we could misunderstand about an agent, which would cause us to make incorrect inferences about the agent’s values:\n", "\n", "The actions of the agent. If we believe that an agent is capable of taking a certain action, but in reality they are not, we might make strange inferences about their values (for instance, that they highly value not taking that action). Furthermore, if our data is e.g. videos of human behavior, we have an additional inference problem of recognizing actions from the frames.\n", "The information available to the agent. If an agent has access to more information than we think it does, then a plan that seems irrational to us (from the perspective of a given reward function) might actually be optimal for reasons that we fail to appreciate. In the other direction, if an agent has less information than we think, then we might incorrectly believe that they don’t value some outcome A, even though they really only failed to obtain A due to lack of information.\n", "\n", "\n", "The long-term plans of the agent. An agent might take many actions that are useful in accomplishing some long-term goal, but not necessarily over the time horizon that we observe the agent. Inferring correct values thus also requires inferring such long-term goals. In addition, long time horizons can make models more brittle, thereby exacerbating model mis-specification issues.\n", "\n", "There are likely other sources of error as well. The general point is that, given a mis-specified model of the agent, it is easy to make incorrect inferences about an agent’s values if the optimization pressure on the learning algorithm is only towards predicting actions correctly in-sample.\n", "In the remainder of this post, we will cover each of the above aspects — actions, information, and plans — in turn, giving both quantitative models and qualitative arguments for why model mis-specification for that aspect of the agent can lead to perverse beliefs and behavior. First, though, we will briefly review the definition of inverse reinforcement learning and introduce relevant notation.\n", "Inverse Reinforcement Learning: Definition and Notations\n", "\n", "In inverse reinforcement learning, we want to model an agent taking actions in a given environment. We therefore suppose that we have a state space (the set of states the agent and environment can be in), an action space (the set of actions the agent can take), and a transition function , which gives the probability of moving from state to state when taking action . For instance, for an AI learning to control a car, the state space would be the possible locations and orientations of the car, the action space would be the set of control signals that the AI could send to the car, and the transition function would be the dynamics model for the car. The tuple of is called an , which is a Markov Decision Process without a reward function. (The will either have a known horizon or a discount rate but we’ll leave these out for simplicity.)\n", "\n", "Figure 1: Diagram showing how IRL and RL are related. (Credit: Pieter Abbeel’s slides on IRL) \n", "The inference problem for IRL is to infer a reward function given an optimal policy for the (see Figure 1). We learn about the policy from samples of states and the corresponding action according to (which may be random). Typically, these samples come from a trajectory, which records the full history of the agent’s states and actions in a single episode:\n", "\n", "In the car example, this would correspond to the actions taken by an expert human driver who is demonstrating desired driving behaviour (where the actions would be recorded as the signals to the steering wheel, brake, etc.).\n", "Given the and the observed trajectory, the goal is to infer the reward function . In a Bayesian framework, if we specify a prior on we have:\n", "\n", "The likelihood is just , where is the optimal policy under the reward function . Note that computing the optimal policy given the reward is in general non-trivial; except in simple cases, we typically approximate the policy using reinforcement learning (see Figure 1). Policies are usually assumed to be noisy (e.g. using a softmax instead of deterministically taking the best action). Due to the challenges of specifying priors, computing optimal policies and integrating over reward functions, most work in IRL uses some kind of approximation to the Bayesian objective (see the references in the introduction for some examples).\n", "Recognizing Human Actions in Data\n", "\n", "IRL is a promising approach to learning human values in part because of the easy availability of data. For supervised learning, humans need to produce many labeled instances specialized for a task. IRL, by contrast, is an unsupervised/semi-supervised approach where any record of human behavior is a potential data source. Facebook’s logs of user behavior provide trillions of data-points. YouTube videos, history books, and literature are a trove of data on human behavior in both actual and imagined scenarios. However, while there is lots of existing data that is informative about human preferences, we argue that exploiting this data for IRL will be a difficult, complex task with current techniques.\n", "Inferring Reward Functions from Video Frames\n", "As we noted above, applications of IRL typically infer the reward function R from observed samples of the human policy . Formally, the environment is a known and the observations are state-action pairs, . This assumes that (a) the environment’s dynamics are given as part of the IRL problem, and (b) the observations are structured as “state-action” pairs. When the data comes from a human expert parking a car, these assumptions are reasonable. The states and actions of the driver can be recorded and a car simulator can be used for . For data from YouTube videos or history books, the assumptions fail. The data is a sequence of partial observations: the transition function is unknown and the data does not separate out state and action. Indeed, it’s a challenging ML problem to infer human actions from text or videos.\n", "\n", "Movie still: What actions are being performed in this situation? (Source)\n", "As a concrete example, suppose the data is a video of two co-pilots flying a plane. The successive frames provide only limited information about the state of the world at each time step and the frames often jump forward in time. So it’s more like a POMDP with a complex observation model. Moreover, the actions of each pilot need to be inferred. This is a challenging inference problem, because actions can be subtle (e.g. when a pilot nudges the controls or nods to his co-pilot).\n", "To infer actions from observations, some model relating the true state-action to the observed video frame must be used. But choosing any model makes substantive assumptions about how human values relate to their behavior. For example, suppose someone attacks one of the pilots and (as a reflex) he defends himself by hitting back. Is this reflexive or instinctive response (hitting the attacker) an action that is informative about the pilot’s values? Philosophers and neuroscientists might investigate this by considering the mental processes that occur before the pilot hits back. If an IRL algorithm uses an off-the-shelf action classifier, it will lock in some (contentious) assumptions about these mental processes. At the same time, an IRL algorithm cannot learn such a model because it never directly observes the mental processes that relate rewards to actions.\n", "Inferring Policies From Video Frames\n", "When learning a reward function via IRL, the ultimate goal is to use the reward function to guide an artificial agent’s behavior (e.g. to perform useful tasks to humans). This goal can be formalized directly, without including IRL as an intermediate step. For example, in Apprenticeship Learning, the goal is to learn a “good” policy for the from samples of the human’s policy (where is assumed to approximately optimize an unknown reward function). In Imitation Learning, the goal is simply to learn a policy that is similar to the human’s policy.\n", "Like IRL, policy search techniques need to recognize an agent’s actions to infer their policy. So they have the same challenges as IRL in learning from videos or history books. Unlike IRL, policy search does not explicitly model the reward function that underlies an agent’s behavior. This leads to an additional challenge. Humans and AI systems face vastly different tasks and have different action spaces. Most actions in videos and books would never be performed by a software agent. Even when tasks are similar (e.g. humans driving in the 1930s vs. a self-driving car in 2016), it is a difficult transfer learning problem to use human policies in one task to improve AI policies in another.\n", "IRL Needs Curated Data\n", "We argued that records of human behaviour in books and videos are difficult for IRL algorithms to exploit. Data from Facebook seems more promising: we can store the state (e.g. the HTML or pixels displayed to the human) and each human action (clicks and scrolling). This extends beyond Facebook to any task that can be performed on a computer. While this covers a broad range of tasks, there are obvious limitations. Many people in the world have a limited ability to use a computer: we can’t learn about their values in this way. Moreover, some kinds of human preferences (e.g. preferences over physical activities) seem hard to learn about from behaviour on a computer.\n", "Information and Biases\n", "\n", "Human actions depend both on their preferences and their beliefs. The beliefs, like the preferences, are never directly observed. For narrow tasks (e.g. people choosing their favorite photos from a display), we can model humans as having full knowledge of the state (as in an MDP). But for most real-world tasks, humans have limited information and their information changes over time (as in a POMDP or RL problem). If IRL assumes the human has full information, then the model is mis-specified and generalizing about what the human would prefer in other scenarios can be mistaken. Here are some examples:\n", "(1). Someone travels from their house to a cafe, which has already closed. If they are assumed to have full knowledge, then IRL would infer an alternative preference (e.g. going for a walk) rather than a preference to get a drink at the cafe.\n", "(2). Someone takes a drug that is widely known to be ineffective. This could be because they have a false belief that the drug is effective, or because they picked up the wrong pill, or because they take the drug for its side-effects. Each possible explanation could lead to different conclusions about preferences.\n", "(3). Suppose an IRL algorithm is inferring a person’s goals from key-presses on their laptop. The person repeatedly forgets their login passwords and has to reset them. This behavior is hard to capture with a POMDP-style model: humans forget some strings of characters and not others. IRL might infer that the person intends to repeatedly reset their passwords.\n", "Example (3) above arises from humans forgetting information — even if the information is only a short string of characters. This is one way in which humans systematically deviate from rational Bayesian agents. The field of psychology has documented many other deviations. Below we discuss one such deviation — time-inconsistency — which has been used to explain temptation, addiction and procrastination.\n", "Time-inconsistency and Procrastination\n", "An IRL algorithm is inferring Alice’s preferences. In particular, the goal is to infer Alice’s preference for completing a somewhat tedious task (e.g. writing a paper) as opposed to relaxing. Alice has days in which she could complete the task and IRL observes her working or relaxing on each successive day.\n", "\n", "Figure 2. MDP graph for choosing whether to “work” or “wait” (relax) on a task. \n", "Formally, let R be the preference/reward Alice assigns to completing the task. Each day, Alice can “work” (receiving cost for doing tedious work) or “wait” (cost ). If she works, she later receives the reward minus a tiny, linearly increasing cost (because it’s better to submit a paper earlier). Beyond the deadline at , Alice cannot get the reward . For IRL, we fix and and infer .\n", "Suppose Alice chooses “wait” on Day 1. If she were fully rational, it follows that R (the preference for completing the task) is small compared to (the psychological cost of doing the tedious work). In other words, Alice doesn’t care much about completing the task. Rational agents will do the task on Day 1 or never do it. Yet humans often care deeply about tasks yet leave them until the last minute (when finishing early would be optimal). Here we imagine that Alice has 9 days to complete the task and waits until the last possible day.\n", "\n", "Figure 3: Graph showing IRL inferences for Optimal model (which is mis-specified) and Possibly Discounting Model (which includes hyperbolic discounting). On each day (-axis) the model gets another observation of Alice’s choice. The -axis shows the posterior mean for (reward for task), where the tedious work . \n", "Figure 3 shows results from running IRL on this problem. There is an “Optimal” model, where the agent is optimal up to an unknown level of softmax random noise (a typical assumption for IRL). There is also a “Possibly Discounting” model, where the agent is either softmax optimal or is a hyperbolic discounter (with unknown level of discounting). We do joint Bayesian inference over the completion reward , the softmax noise and (for “Possibly Discounting”) how much the agent hyperbolically discounts. The work cost is set to . Figure 3 shows that after 6 days of observing Alice procrastinate, the “Optimal” model is very confident that Alice does not care about the task . When Alice completes the task on the last possible day, the posterior mean on R is not much more than the prior mean. By contrast, the “Possibly Discounting” model never becomes confident that Alice doesn’t care about the task. (Note that the gap between the models would be bigger for larger . The “Optimal” model’s posterior on R shoots back to its Day-0 prior because it explains the whole action sequence as due to high softmax noise — optimal agents without noise would either do the task immediately or not at all. Full details and code are here.)\n", "Long-term Plans\n", "\n", "Agents will often take long series of actions that generate negative utility for them in the moment in order to accomplish a long-term goal (for instance, studying every night in order to perform well on a test). Such long-term plans can make IRL more difficult for a few reasons. Here we focus on two: (1) IRL systems may not have access to the right type of data for learning about long-term goals, and (2) needing to predict long sequences of actions can make algorithms more fragile in the face of model mis-specification.\n", "(1) Wrong type of data. To make inferences based on long-term plans, it would be helpful to have coherent data about a single agent’s actions over a long period of time (so that we can e.g. see the plan unfolding). But in practice we will likely have substantially more data consisting of short snapshots of a large number of different agents (e.g. because many internet services already record user interactions, but it is uncommon for a single person to be exhaustively tracked and recorded over an extended period of time even while they are offline).\n", "The former type of data (about a single representative population measured over time) is called panel data, while the latter type of data (about different representative populations measured at each point in time) is called repeated cross-section data. The differences between these two types of data is well-studied in econometrics, and a general theme is the following: it is difficult to infer individual-level effects from cross-sectional data.\n", "An easy and familiar example of this difference (albeit not in an IRL setting) can be given in terms of election campaigns. Most campaign polling is cross-sectional in nature: a different population of respondents is polled at each point in time. Suppose that Hillary Clinton gives a speech and her overall support according to cross-sectional polls increases by 2%; what can we conclude from this? Does it mean that 2% of people switched from Trump to Clinton? Or did 6% of people switch from Trump to Clinton while 4% switched from Clinton to Trump?\n", "At a minimum, then, using cross-sectional data leads to a difficult disaggregation problem; for instance, different agents taking different actions at a given point in time could be due to being at different stages in the same plan, or due to having different plans, or some combination of these and other factors. Collecting demographic and other side data can help us (by allowing us to look at variation and shifts within each subpopulation), but it is unclear if this will be sufficient in general.\n", "On the other hand, there are some services (such as Facebook or Google) that do have extensive data about individual users across a long period of time. However, this data has another issue: it is incomplete in a very systematic way (since it only tracks online behaviour). For instance, someone might go online most days to read course notes and Wikipedia for a class; this is data that would likely be recorded. However, it is less likely that one would have a record of that person taking the final exam, passing the class and then getting an internship based on their class performance. Of course, some pieces of this sequence would be inferable based on some people’s e-mail records, etc., but it would likely be under-represented in the data relative to the record of Wikipedia usage. In either case, some non-trivial degree of inference would be necessary to make sense of such data.\n", "(2) Fragility to mis-specification. Above we discussed why observing only short sequences of actions from an agent can make it difficult to learn about their long-term plans (and hence to reason correctly about their values). Next we discuss another potential issue — fragility to model mis-specification.\n", "Suppose someone spends 99 days doing a boring task to accomplish an important goal on day 100. A system that is only trying to correctly predict actions will be right 99% of the time if it predicts that the person inherently enjoys boring tasks. Of course, a system that understands the goal and how the tasks lead to the goal will be right 100% of the time, but even minor errors in its understanding could bring the accuracy back below 99%.\n", "The general issue is the following: large changes in the model of the agent might only lead to small changes in the predictive accuracy of the model, and the longer the time horizon on which a goal is realized, the more this might be the case. This means that even slight mis-specifications in the model could tip the scales back in favor of a (very) incorrect reward function. A potential way of dealing with this might be to identify “important” predictions that seem closely tied to the reward function, and focus particularly on getting those predictions right (see here for a paper exploring a similar idea in the context of approximate inference).\n", "One might object that this is only a problem in this toy setting; for instance, in the real world, one might look at the particular way in which someone is studying or performing some other boring task to see that it coherently leads towards some goal (in a way that would be less likely were the person to be doing something boring purely for enjoyment). In other words, correctly understanding the agent’s goals might allow for more fine-grained accurate predictions which would fare better under e.g. log-score than would an incorrect model.\n", "This is a reasonable objection, but there are some historical examples of this going wrong that should give one pause. That is, there are historical instances where: (i) people expected a more complex model that seemed to get at some underlying mechanism to outperform a simpler model that ignored that mechanism, and (ii) they were wrong (the simpler model did better under log-score). The example we are most familiar with is n-gram models vs. parse trees for language modelling; the most successful language models (in terms of having the best log-score on predicting the next word given a sequence of previous words) essentially treat language as a high-order Markov chain or hidden Markov model, despite the fact that linguistic theory predicts that language should be tree-structured rather than linearly-structured. Indeed, NLP researchers have tried building language models that assume language is tree-structured, and these models perform worse, or at least do not seem to have been adopted in practice (this is true both for older discrete models and newer continuous models based on neural nets).  It’s plausible that a similar issue will occur in inverse reinforcement learning, where correctly inferring plans is not enough to win out in predictive performance. The reason for the two issues might be quite similar (in language modelling, the tree structure only wins out in statistically uncommon corner cases involving long-term and/or nested dependencies, and hence getting that part of the prediction correct doesn’t help predictive accuracy much).\n", "The overall point is: in the case of even slight model mis-specification, the “correct” model might actually perform worse under typical metrics such as predictive accuracy. Therefore, more careful methods of constructing a model might be necessary.\n", "Learning Values != Robustly Predicting Human Behaviour\n", "\n", "The problems with IRL described so far will result in poor performance for predicting human choices out-of-sample. For example, if someone is observed doing boring tasks for 99 days (where they only achieve the goal on Day 100), they’ll be predicted to continue doing boring tasks even when a short-cut to the goal becomes available. So even if the goal is simply to predict human behaviour (not to infer human values), mis-specification leads to bad predictions on realistic out-of-sample scenarios.\n", "Let’s suppose that our goal is not to predict human behaviour but to create AI systems that promote and respect human values. These goals (predicting humans and building safe AI) are distinct. Here’s an example that illustrates the difference. Consider a long-term smoker, Bob, who would continue smoking even if there were (counterfactually) a universally effective anti-smoking treatment. Maybe Bob is in denial about the health effects of smoking or Bob thinks he’ll inevitably go back to smoking whatever happens. If an AI system were assisting Bob, we might expect it to avoid promoting his smoking habit (e.g. by not offering him cigarettes at random moments). This is not paternalism, where the AI system imposes someone else’s values on Bob. The point is that even if Bob would continue smoking across many counterfactual scenarios this doesn’t mean that he places value on smoking.\n", "How do we choose between the theory that Bob values smoking and the theory that he does not (but smokes anyway because of the powerful addiction)? Humans choose between these theories based on our experience with addictive behaviours and our insights into people’s preferences and values. This kind of insight can’t easily be captured as formal assumptions about a model, or even as a criterion about counterfactual generalization. (The theory that Bob values smoking does make accurate predictions across a wide range of counterfactuals.) Because of this, learning human values from IRL has a more profound kind of model mis-specification than the examples in Jacob’s previous post. Even in the limit of data generated from an infinite series of random counterfactual scenarios, standard IRL algorithms would not infer someone’s true values.\n", "Predicting human actions is neither necessary nor sufficient for learning human values. In what ways, then, are the two related? One such way stems from the premise that if someone spends more resources making a decision, the resulting decision tends to be more in keeping with their true values. For instance, someone might spend lots of time thinking about the decision, they might consult experts, or they might try out the different options in a trial period before they make the real decision. Various authors have thus suggested that people’s choices under sufficient “reflection” act as a reliable indicator of their true values. Under this view, predicting a certain kind of behaviour (choices under reflection) is sufficient for learning human values. Paul Christiano has written about some proposals for doing this, though we will not discuss them here (the first link is for general AI systems while the second is for newsfeeds). In general, turning these ideas into algorithms that are tractable and learn safely remains a challenging problem.\n", "Further reading\n", "\n", "There is research on doing IRL for agents in POMDPs. Owain and collaborators explored the effects of limited information and cognitive biases on IRL: paper, paper, online book.\n", "For many environments it will not be possible to identify the reward function from the observed trajectories. These identification problems are related to the mis-specification problems but are not the same thing. Active learning can help with identification (paper).\n", "Paul Christiano raised many similar points about mis-specification in a post on his blog.\n", "For a big-picture monograph on relations between human preferences, economic utility theory and welfare/well-being, see Hausman’s “Preference, Value, Choice and Welfare”.\n", "Acknowledgments\n", "\n", "Thanks to Sindy Li for reviewing a full draft of this post and providing many helpful comments. Thanks also to Michael Webb and Paul Christiano for doing the same on specific sections of the post.\n" ] } ], "source": [ "article_num = 73\n", "\n", "example_article_metadata = dataset.metadata[article_num]\n", "print(f\"Title: {example_article_metadata[0]}\")\n", "print(f\"Author: {example_article_metadata[1]}\")\n", "print(f\"Date published: {example_article_metadata[2]}\")\n", "print(f\"URL: {example_article_metadata[3]}\")\n", "print(f\"Tags: {example_article_metadata[4]}\")\n", "print(f\"Text: {example_article_metadata[5]}\")\n" ] }, { "cell_type": "code", "execution_count": 133, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Articles count: 140\n", "Num of each source: defaultdict(, {'https://aipulse.org': 23, 'manual': 1, 'waitbutwhy.com': 2, 'https://vkrakovna.wordpress.com': 43, 'https://jsteinhardt.wordpress.com': 39, 'https://aisafety.camp': 8, 'curriculum': 1, 'https://www.yudkowsky.net': 23})\n", "Num chars: 2096402\n", "Num words: 335374\n", "Num sentences: 16648\n", "Num blocks: 1818\n" ] } ], "source": [ "print(f\"Articles count: {len(dataset.metadata)}\")\n", "print(f\"Num of each source: {dataset.articles_count}\")\n", "print(f\"Num chars: {dataset.total_char_count}\")\n", "print(f\"Num words: {dataset.total_word_count}\")\n", "print(f\"Num sentences: {dataset.total_sentence_count}\")\n", "print(f\"Num blocks: {dataset.total_block_count}\")" ] }, { "cell_type": "code", "execution_count": 139, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Completed 50/1818 embeddings in 1.75 seconds.\n", "Completed 100/1818 embeddings in 2.48 seconds.\n", "Completed 150/1818 embeddings in 3.32 seconds.\n", "Completed 200/1818 embeddings in 4.09 seconds.\n", "Completed 250/1818 embeddings in 4.94 seconds.\n", "Completed 300/1818 embeddings in 5.83 seconds.\n", "Completed 350/1818 embeddings in 6.62 seconds.\n", "Completed 400/1818 embeddings in 7.43 seconds.\n", "Completed 450/1818 embeddings in 8.23 seconds.\n", "Completed 500/1818 embeddings in 8.90 seconds.\n", "Completed 550/1818 embeddings in 9.60 seconds.\n", "Completed 600/1818 embeddings in 10.39 seconds.\n", "Completed 650/1818 embeddings in 11.25 seconds.\n", "Completed 700/1818 embeddings in 11.92 seconds.\n", "Completed 750/1818 embeddings in 12.73 seconds.\n", "Completed 800/1818 embeddings in 13.69 seconds.\n", "Completed 850/1818 embeddings in 14.88 seconds.\n", "Completed 900/1818 embeddings in 16.02 seconds.\n", "Completed 950/1818 embeddings in 17.34 seconds.\n", "Completed 1000/1818 embeddings in 18.22 seconds.\n", "Completed 1050/1818 embeddings in 19.32 seconds.\n", "Completed 1100/1818 embeddings in 20.44 seconds.\n", "Completed 1150/1818 embeddings in 21.32 seconds.\n", "Completed 1200/1818 embeddings in 22.53 seconds.\n", "Completed 1250/1818 embeddings in 23.46 seconds.\n", "Completed 1300/1818 embeddings in 24.64 seconds.\n", "Completed 1350/1818 embeddings in 25.58 seconds.\n", "Completed 1400/1818 embeddings in 26.62 seconds.\n", "Completed 1450/1818 embeddings in 27.54 seconds.\n", "Completed 1500/1818 embeddings in 28.60 seconds.\n", "Completed 1550/1818 embeddings in 29.78 seconds.\n", "Completed 1600/1818 embeddings in 30.82 seconds.\n", "Completed 1650/1818 embeddings in 31.79 seconds.\n", "Completed 1700/1818 embeddings in 32.79 seconds.\n", "Completed 1750/1818 embeddings in 34.00 seconds.\n", "Completed 1800/1818 embeddings in 35.08 seconds.\n", "Completed 1818/1818 embeddings in 36.30 seconds.\n" ] } ], "source": [ "dataset.get_embeddings()\n", "dataset.save_embeddings(PATH_TO_EMBEDDINGS)" ] }, { "cell_type": "code", "execution_count": 140, "metadata": {}, "outputs": [], "source": [ "dataset.save_class(PATH_TO_DATASET)" ] }, { "cell_type": "code", "execution_count": 141, "metadata": {}, "outputs": [], "source": [ "# for embed in dataset.embedding_strings:\n", "# print(embed)\n", "# print(\"\\n\"*4)" ] }, { "cell_type": "code", "execution_count": 142, "metadata": {}, "outputs": [], "source": [ "\"\"\"\n", "TODO:\n", "Add a moderation call to not be prompt-hacked: https://platform.openai.com/docs/guides/moderation/quickstart\n", "\"\"\"\n", "\n", "class AlignmentSearch:\n", " def __init__(self,\n", " dataset: Dataset, # Dataset object containing the data.\n", " ):\n", " self.metadataset = dataset\n", " \n", " @retry(wait=wait_random_exponential(min=1, max=20), stop=stop_after_attempt(4))\n", " def get_embedding(self, text: str) -> np.ndarray:\n", " result = openai.Embedding.create(model=EMBEDDING_MODEL, input=text)\n", " print(f\"Embedding created for query: {text}\")\n", " return result[\"data\"][0][\"embedding\"]\n", " # except openai.RateLimitError as e:\n", " # print(\"Rate limit exceeded. Retrying in 30 seconds.\")\n", " # time.sleep(30)\n", " # raise e\n", " \n", " def get_top_k(self, query: str, k: int=10) -> List[str]:\n", " # Receives a query (str) and returns the top k blocks that are most semantically similar to the query.\n", " # Each tuple contains the title of an article, its URL, and text.\n", " query_embedding = self.get_embedding(query)\n", " similarities = np.dot(self.metadataset.embeddings, query_embedding)\n", " top_k_indices = np.argsort(similarities)[::-1][:k]\n", " top_k = [self.metadataset.embedding_strings[i] for i in top_k_indices]\n", " return top_k\n", " \n", " def limit_tokens(self, text: str, max_tokens: int, encoding_name: str = \"cl100k_base\") -> str:\n", " encoding = tiktoken.get_encoding(encoding_name)\n", " tokens = encoding.encode(text)[:max_tokens]\n", " return encoding.decode(tokens)\n", " \n", " def construct_messages(self, question: str, blocks: List[str] = None, mode: str = \"balanced\") -> str:\n", " # Receives a question (str) and a list of blocks and returns a prompt (str) to be used for text generation.\n", " context = \"\"\n", " if blocks:\n", " for i, block in enumerate(blocks):\n", " context += f'Context #{i+1}: \"\"\"{block}\"\"\"\\n\\n'\n", " context = self.limit_tokens(context, 2000)\n", "\n", " if mode == \"creative\":\n", " raise NotImplementedError\n", "\n", " elif mode == \"balanced\":\n", " system = '''You are a helpful assistant.'''\n", " user_prompt = '''You help users by answering questions and providing information about AI Alignment and AI Safety. You are extremely knowledgeable, yet you know the limits of your knowledge. Answer the questions as truthfully as possible using the provided context blocks, and if the answer is not contained within them, say, \"I don't know.\" You can also ask the user questions to clarify their query.'''\n", " \n", " messages = [\n", " {\"role\": \"system\", \"content\": system},\n", " {\"role\": \"user\", \"content\": f\"{user_prompt}\\n\\n{context}\\n\\nQuestion: {question}\"}\n", " ]\n", " \n", " elif mode == \"precise\":\n", " raise NotImplementedError\n", "\n", " elif mode == \"HyDE\":\n", " assistant_prompt = \"You are a helpful assistant, and you help users by answering questions and providing information about AI Alignment and AI Safety, on which you are extremely knowledgeable. Answer the user's question even if you are not certain of the answer; it is supremely important that you do attempt to offer an answer related to the user's query.\"\n", " messages = [\n", " {\"role\": \"system\", \"content\": assistant_prompt},\n", " {\"role\": \"user\", \"content\": question},\n", " ]\n", " \n", " else:\n", " raise ValueError(\"Mode must be one of 'balanced', 'precise', 'creative', or 'HyDE'.\")\n", " \n", " return messages\n", " \n", " def answer_question(self, question: str, blocks: List[str]) -> str:\n", " # Receives a question (str) and a list of blocks and returns an answer (str) to the question.\n", " messages = self.construct_messages(question, blocks, mode=\"balanced\")\n", " answer = openai.ChatCompletion.create(\n", " model=COMPLETIONS_MODEL, \n", " messages=messages\n", " )\n", " return answer[\"choices\"][0][\"message\"][\"content\"]\n", " \n", " def search_and_answer(self, question: str, k: int=10, HyDE: bool=False) -> str:\n", " # Receives a question (str) and returns an answer (str) to the question.\n", " if HyDE:\n", " messages = self.construct_messages(question, mode=\"HyDE\")\n", " hyde_completion = openai.ChatCompletion.create(\n", " model=COMPLETIONS_MODEL, \n", " messages=messages\n", " )\n", " top_k = self.get_top_k(f\"{question}\\n{hyde_completion}\", k)\n", " else:\n", " top_k = self.get_top_k(question, k)\n", " answer = self.answer_question(question, top_k)\n", " return answer, top_k# , sources" ] }, { "cell_type": "code", "execution_count": 156, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Embedding created for query: Recognizing Human Actions in Data\n", "IRL is a promising approach to learning human values in part because of the easy availability of data. For supervised learning, humans need to produce many labeled instances specialized for a task. IRL, by contrast, is an unsupervised/semi-supervised approach where any record of human behavior is a potential data source. Facebook’s logs of user behavior provide trillions of data-points. YouTube videos, history books, and literature are a trove of data on human behavior in both actual and imagined scenarios. However, while there is lots of existing data that is informative about human preferences, we argue that exploiting this data for IRL will be a difficult, complex task with current techniques.\n" ] }, { "ename": "KeyboardInterrupt", "evalue": "", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", "Cell \u001b[1;32mIn[156], line 6\u001b[0m\n\u001b[0;32m 3\u001b[0m query \u001b[39m=\u001b[39m \u001b[39m\"\"\"\u001b[39m\u001b[39mRecognizing Human Actions in Data\u001b[39m\n\u001b[0;32m 4\u001b[0m \u001b[39mIRL is a promising approach to learning human values in part because of the easy availability of data. For supervised learning, humans need to produce many labeled instances specialized for a task. IRL, by contrast, is an unsupervised/semi-supervised approach where any record of human behavior is a potential data source. Facebook’s logs of user behavior provide trillions of data-points. YouTube videos, history books, and literature are a trove of data on human behavior in both actual and imagined scenarios. However, while there is lots of existing data that is informative about human preferences, we argue that exploiting this data for IRL will be a difficult, complex task with current techniques.\u001b[39m\u001b[39m\"\"\"\u001b[39m\n\u001b[0;32m 5\u001b[0m \u001b[39m# top_k_sources = AS.get_top_k(query, k)\u001b[39;00m\n\u001b[1;32m----> 6\u001b[0m answer, top_k_sources \u001b[39m=\u001b[39m AS\u001b[39m.\u001b[39;49msearch_and_answer(query, k)\u001b[39m#, HyDE=True)\u001b[39;00m\n\u001b[0;32m 7\u001b[0m \u001b[39mprint\u001b[39m(answer)\n", "Cell \u001b[1;32mIn[142], line 93\u001b[0m, in \u001b[0;36mAlignmentSearch.search_and_answer\u001b[1;34m(self, question, k, HyDE)\u001b[0m\n\u001b[0;32m 91\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m 92\u001b[0m top_k \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mget_top_k(question, k)\n\u001b[1;32m---> 93\u001b[0m answer \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49manswer_question(question, top_k)\n\u001b[0;32m 94\u001b[0m \u001b[39mreturn\u001b[39;00m answer, top_k\n", "Cell \u001b[1;32mIn[142], line 76\u001b[0m, in \u001b[0;36mAlignmentSearch.answer_question\u001b[1;34m(self, question, blocks)\u001b[0m\n\u001b[0;32m 73\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39manswer_question\u001b[39m(\u001b[39mself\u001b[39m, question: \u001b[39mstr\u001b[39m, blocks: List[\u001b[39mstr\u001b[39m]) \u001b[39m-\u001b[39m\u001b[39m>\u001b[39m \u001b[39mstr\u001b[39m:\n\u001b[0;32m 74\u001b[0m \u001b[39m# Receives a question (str) and a list of blocks and returns an answer (str) to the question.\u001b[39;00m\n\u001b[0;32m 75\u001b[0m messages \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mconstruct_messages(question, blocks, mode\u001b[39m=\u001b[39m\u001b[39m\"\u001b[39m\u001b[39mbalanced\u001b[39m\u001b[39m\"\u001b[39m)\n\u001b[1;32m---> 76\u001b[0m answer \u001b[39m=\u001b[39m openai\u001b[39m.\u001b[39;49mChatCompletion\u001b[39m.\u001b[39;49mcreate(\n\u001b[0;32m 77\u001b[0m model\u001b[39m=\u001b[39;49mCOMPLETIONS_MODEL, \n\u001b[0;32m 78\u001b[0m messages\u001b[39m=\u001b[39;49mmessages\n\u001b[0;32m 79\u001b[0m )\n\u001b[0;32m 80\u001b[0m \u001b[39mreturn\u001b[39;00m answer[\u001b[39m\"\u001b[39m\u001b[39mchoices\u001b[39m\u001b[39m\"\u001b[39m][\u001b[39m0\u001b[39m][\u001b[39m\"\u001b[39m\u001b[39mmessage\u001b[39m\u001b[39m\"\u001b[39m][\u001b[39m\"\u001b[39m\u001b[39mcontent\u001b[39m\u001b[39m\"\u001b[39m]\n", "File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python310\\site-packages\\openai\\api_resources\\chat_completion.py:25\u001b[0m, in \u001b[0;36mChatCompletion.create\u001b[1;34m(cls, *args, **kwargs)\u001b[0m\n\u001b[0;32m 23\u001b[0m \u001b[39mwhile\u001b[39;00m \u001b[39mTrue\u001b[39;00m:\n\u001b[0;32m 24\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[1;32m---> 25\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39msuper\u001b[39m()\u001b[39m.\u001b[39mcreate(\u001b[39m*\u001b[39margs, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mkwargs)\n\u001b[0;32m 26\u001b[0m \u001b[39mexcept\u001b[39;00m TryAgain \u001b[39mas\u001b[39;00m e:\n\u001b[0;32m 27\u001b[0m \u001b[39mif\u001b[39;00m timeout \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m \u001b[39mand\u001b[39;00m time\u001b[39m.\u001b[39mtime() \u001b[39m>\u001b[39m start \u001b[39m+\u001b[39m timeout:\n", "File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python310\\site-packages\\openai\\api_resources\\abstract\\engine_api_resource.py:153\u001b[0m, in \u001b[0;36mEngineAPIResource.create\u001b[1;34m(cls, api_key, api_base, api_type, request_id, api_version, organization, **params)\u001b[0m\n\u001b[0;32m 127\u001b[0m \u001b[39m@classmethod\u001b[39m\n\u001b[0;32m 128\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mcreate\u001b[39m(\n\u001b[0;32m 129\u001b[0m \u001b[39mcls\u001b[39m,\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 136\u001b[0m \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mparams,\n\u001b[0;32m 137\u001b[0m ):\n\u001b[0;32m 138\u001b[0m (\n\u001b[0;32m 139\u001b[0m deployment_id,\n\u001b[0;32m 140\u001b[0m engine,\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 150\u001b[0m api_key, api_base, api_type, api_version, organization, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mparams\n\u001b[0;32m 151\u001b[0m )\n\u001b[1;32m--> 153\u001b[0m response, _, api_key \u001b[39m=\u001b[39m requestor\u001b[39m.\u001b[39;49mrequest(\n\u001b[0;32m 154\u001b[0m \u001b[39m\"\u001b[39;49m\u001b[39mpost\u001b[39;49m\u001b[39m\"\u001b[39;49m,\n\u001b[0;32m 155\u001b[0m url,\n\u001b[0;32m 156\u001b[0m params\u001b[39m=\u001b[39;49mparams,\n\u001b[0;32m 157\u001b[0m headers\u001b[39m=\u001b[39;49mheaders,\n\u001b[0;32m 158\u001b[0m stream\u001b[39m=\u001b[39;49mstream,\n\u001b[0;32m 159\u001b[0m request_id\u001b[39m=\u001b[39;49mrequest_id,\n\u001b[0;32m 160\u001b[0m request_timeout\u001b[39m=\u001b[39;49mrequest_timeout,\n\u001b[0;32m 161\u001b[0m )\n\u001b[0;32m 163\u001b[0m \u001b[39mif\u001b[39;00m stream:\n\u001b[0;32m 164\u001b[0m \u001b[39m# must be an iterator\u001b[39;00m\n\u001b[0;32m 165\u001b[0m \u001b[39massert\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39misinstance\u001b[39m(response, OpenAIResponse)\n", "File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python310\\site-packages\\openai\\api_requestor.py:216\u001b[0m, in \u001b[0;36mAPIRequestor.request\u001b[1;34m(self, method, url, params, headers, files, stream, request_id, request_timeout)\u001b[0m\n\u001b[0;32m 205\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mrequest\u001b[39m(\n\u001b[0;32m 206\u001b[0m \u001b[39mself\u001b[39m,\n\u001b[0;32m 207\u001b[0m method,\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 214\u001b[0m request_timeout: Optional[Union[\u001b[39mfloat\u001b[39m, Tuple[\u001b[39mfloat\u001b[39m, \u001b[39mfloat\u001b[39m]]] \u001b[39m=\u001b[39m \u001b[39mNone\u001b[39;00m,\n\u001b[0;32m 215\u001b[0m ) \u001b[39m-\u001b[39m\u001b[39m>\u001b[39m Tuple[Union[OpenAIResponse, Iterator[OpenAIResponse]], \u001b[39mbool\u001b[39m, \u001b[39mstr\u001b[39m]:\n\u001b[1;32m--> 216\u001b[0m result \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mrequest_raw(\n\u001b[0;32m 217\u001b[0m method\u001b[39m.\u001b[39;49mlower(),\n\u001b[0;32m 218\u001b[0m url,\n\u001b[0;32m 219\u001b[0m params\u001b[39m=\u001b[39;49mparams,\n\u001b[0;32m 220\u001b[0m supplied_headers\u001b[39m=\u001b[39;49mheaders,\n\u001b[0;32m 221\u001b[0m files\u001b[39m=\u001b[39;49mfiles,\n\u001b[0;32m 222\u001b[0m stream\u001b[39m=\u001b[39;49mstream,\n\u001b[0;32m 223\u001b[0m request_id\u001b[39m=\u001b[39;49mrequest_id,\n\u001b[0;32m 224\u001b[0m request_timeout\u001b[39m=\u001b[39;49mrequest_timeout,\n\u001b[0;32m 225\u001b[0m )\n\u001b[0;32m 226\u001b[0m resp, got_stream \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_interpret_response(result, stream)\n\u001b[0;32m 227\u001b[0m \u001b[39mreturn\u001b[39;00m resp, got_stream, \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mapi_key\n", "File \u001b[1;32m~\\AppData\\Roaming\\Python\\Python310\\site-packages\\openai\\api_requestor.py:516\u001b[0m, in \u001b[0;36mAPIRequestor.request_raw\u001b[1;34m(self, method, url, params, supplied_headers, files, stream, request_id, request_timeout)\u001b[0m\n\u001b[0;32m 514\u001b[0m _thread_context\u001b[39m.\u001b[39msession \u001b[39m=\u001b[39m _make_session()\n\u001b[0;32m 515\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[1;32m--> 516\u001b[0m result \u001b[39m=\u001b[39m _thread_context\u001b[39m.\u001b[39;49msession\u001b[39m.\u001b[39;49mrequest(\n\u001b[0;32m 517\u001b[0m method,\n\u001b[0;32m 518\u001b[0m abs_url,\n\u001b[0;32m 519\u001b[0m headers\u001b[39m=\u001b[39;49mheaders,\n\u001b[0;32m 520\u001b[0m data\u001b[39m=\u001b[39;49mdata,\n\u001b[0;32m 521\u001b[0m files\u001b[39m=\u001b[39;49mfiles,\n\u001b[0;32m 522\u001b[0m stream\u001b[39m=\u001b[39;49mstream,\n\u001b[0;32m 523\u001b[0m timeout\u001b[39m=\u001b[39;49mrequest_timeout \u001b[39mif\u001b[39;49;00m request_timeout \u001b[39melse\u001b[39;49;00m TIMEOUT_SECS,\n\u001b[0;32m 524\u001b[0m )\n\u001b[0;32m 525\u001b[0m \u001b[39mexcept\u001b[39;00m requests\u001b[39m.\u001b[39mexceptions\u001b[39m.\u001b[39mTimeout \u001b[39mas\u001b[39;00m e:\n\u001b[0;32m 526\u001b[0m \u001b[39mraise\u001b[39;00m error\u001b[39m.\u001b[39mTimeout(\u001b[39m\"\u001b[39m\u001b[39mRequest timed out: \u001b[39m\u001b[39m{}\u001b[39;00m\u001b[39m\"\u001b[39m\u001b[39m.\u001b[39mformat(e)) \u001b[39mfrom\u001b[39;00m \u001b[39me\u001b[39;00m\n", "File \u001b[1;32mc:\\Python310\\lib\\site-packages\\requests\\sessions.py:587\u001b[0m, in \u001b[0;36mSession.request\u001b[1;34m(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)\u001b[0m\n\u001b[0;32m 582\u001b[0m send_kwargs \u001b[39m=\u001b[39m {\n\u001b[0;32m 583\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mtimeout\u001b[39m\u001b[39m\"\u001b[39m: timeout,\n\u001b[0;32m 584\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mallow_redirects\u001b[39m\u001b[39m\"\u001b[39m: allow_redirects,\n\u001b[0;32m 585\u001b[0m }\n\u001b[0;32m 586\u001b[0m send_kwargs\u001b[39m.\u001b[39mupdate(settings)\n\u001b[1;32m--> 587\u001b[0m resp \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39msend(prep, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39msend_kwargs)\n\u001b[0;32m 589\u001b[0m \u001b[39mreturn\u001b[39;00m resp\n", "File \u001b[1;32mc:\\Python310\\lib\\site-packages\\requests\\sessions.py:701\u001b[0m, in \u001b[0;36mSession.send\u001b[1;34m(self, request, **kwargs)\u001b[0m\n\u001b[0;32m 698\u001b[0m start \u001b[39m=\u001b[39m preferred_clock()\n\u001b[0;32m 700\u001b[0m \u001b[39m# Send the request\u001b[39;00m\n\u001b[1;32m--> 701\u001b[0m r \u001b[39m=\u001b[39m adapter\u001b[39m.\u001b[39msend(request, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mkwargs)\n\u001b[0;32m 703\u001b[0m \u001b[39m# Total elapsed time of the request (approximately)\u001b[39;00m\n\u001b[0;32m 704\u001b[0m elapsed \u001b[39m=\u001b[39m preferred_clock() \u001b[39m-\u001b[39m start\n", "File \u001b[1;32mc:\\Python310\\lib\\site-packages\\requests\\adapters.py:489\u001b[0m, in \u001b[0;36mHTTPAdapter.send\u001b[1;34m(self, request, stream, timeout, verify, cert, proxies)\u001b[0m\n\u001b[0;32m 487\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[0;32m 488\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m chunked:\n\u001b[1;32m--> 489\u001b[0m resp \u001b[39m=\u001b[39m conn\u001b[39m.\u001b[39;49murlopen(\n\u001b[0;32m 490\u001b[0m method\u001b[39m=\u001b[39;49mrequest\u001b[39m.\u001b[39;49mmethod,\n\u001b[0;32m 491\u001b[0m url\u001b[39m=\u001b[39;49murl,\n\u001b[0;32m 492\u001b[0m body\u001b[39m=\u001b[39;49mrequest\u001b[39m.\u001b[39;49mbody,\n\u001b[0;32m 493\u001b[0m headers\u001b[39m=\u001b[39;49mrequest\u001b[39m.\u001b[39;49mheaders,\n\u001b[0;32m 494\u001b[0m redirect\u001b[39m=\u001b[39;49m\u001b[39mFalse\u001b[39;49;00m,\n\u001b[0;32m 495\u001b[0m assert_same_host\u001b[39m=\u001b[39;49m\u001b[39mFalse\u001b[39;49;00m,\n\u001b[0;32m 496\u001b[0m preload_content\u001b[39m=\u001b[39;49m\u001b[39mFalse\u001b[39;49;00m,\n\u001b[0;32m 497\u001b[0m decode_content\u001b[39m=\u001b[39;49m\u001b[39mFalse\u001b[39;49;00m,\n\u001b[0;32m 498\u001b[0m retries\u001b[39m=\u001b[39;49m\u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mmax_retries,\n\u001b[0;32m 499\u001b[0m timeout\u001b[39m=\u001b[39;49mtimeout,\n\u001b[0;32m 500\u001b[0m )\n\u001b[0;32m 502\u001b[0m \u001b[39m# Send the request.\u001b[39;00m\n\u001b[0;32m 503\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m 504\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mhasattr\u001b[39m(conn, \u001b[39m\"\u001b[39m\u001b[39mproxy_pool\u001b[39m\u001b[39m\"\u001b[39m):\n", "File \u001b[1;32mc:\\Python310\\lib\\site-packages\\urllib3\\connectionpool.py:703\u001b[0m, in \u001b[0;36mHTTPConnectionPool.urlopen\u001b[1;34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw)\u001b[0m\n\u001b[0;32m 700\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_prepare_proxy(conn)\n\u001b[0;32m 702\u001b[0m \u001b[39m# Make the request on the httplib connection object.\u001b[39;00m\n\u001b[1;32m--> 703\u001b[0m httplib_response \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_make_request(\n\u001b[0;32m 704\u001b[0m conn,\n\u001b[0;32m 705\u001b[0m method,\n\u001b[0;32m 706\u001b[0m url,\n\u001b[0;32m 707\u001b[0m timeout\u001b[39m=\u001b[39;49mtimeout_obj,\n\u001b[0;32m 708\u001b[0m body\u001b[39m=\u001b[39;49mbody,\n\u001b[0;32m 709\u001b[0m headers\u001b[39m=\u001b[39;49mheaders,\n\u001b[0;32m 710\u001b[0m chunked\u001b[39m=\u001b[39;49mchunked,\n\u001b[0;32m 711\u001b[0m )\n\u001b[0;32m 713\u001b[0m \u001b[39m# If we're going to release the connection in ``finally:``, then\u001b[39;00m\n\u001b[0;32m 714\u001b[0m \u001b[39m# the response doesn't need to know about the connection. Otherwise\u001b[39;00m\n\u001b[0;32m 715\u001b[0m \u001b[39m# it will also try to release it and we'll have a double-release\u001b[39;00m\n\u001b[0;32m 716\u001b[0m \u001b[39m# mess.\u001b[39;00m\n\u001b[0;32m 717\u001b[0m response_conn \u001b[39m=\u001b[39m conn \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m release_conn \u001b[39melse\u001b[39;00m \u001b[39mNone\u001b[39;00m\n", "File \u001b[1;32mc:\\Python310\\lib\\site-packages\\urllib3\\connectionpool.py:449\u001b[0m, in \u001b[0;36mHTTPConnectionPool._make_request\u001b[1;34m(self, conn, method, url, timeout, chunked, **httplib_request_kw)\u001b[0m\n\u001b[0;32m 444\u001b[0m httplib_response \u001b[39m=\u001b[39m conn\u001b[39m.\u001b[39mgetresponse()\n\u001b[0;32m 445\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mBaseException\u001b[39;00m \u001b[39mas\u001b[39;00m e:\n\u001b[0;32m 446\u001b[0m \u001b[39m# Remove the TypeError from the exception chain in\u001b[39;00m\n\u001b[0;32m 447\u001b[0m \u001b[39m# Python 3 (including for exceptions like SystemExit).\u001b[39;00m\n\u001b[0;32m 448\u001b[0m \u001b[39m# Otherwise it looks like a bug in the code.\u001b[39;00m\n\u001b[1;32m--> 449\u001b[0m six\u001b[39m.\u001b[39;49mraise_from(e, \u001b[39mNone\u001b[39;49;00m)\n\u001b[0;32m 450\u001b[0m \u001b[39mexcept\u001b[39;00m (SocketTimeout, BaseSSLError, SocketError) \u001b[39mas\u001b[39;00m e:\n\u001b[0;32m 451\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_raise_timeout(err\u001b[39m=\u001b[39me, url\u001b[39m=\u001b[39murl, timeout_value\u001b[39m=\u001b[39mread_timeout)\n", "File \u001b[1;32m:3\u001b[0m, in \u001b[0;36mraise_from\u001b[1;34m(value, from_value)\u001b[0m\n", "File \u001b[1;32mc:\\Python310\\lib\\site-packages\\urllib3\\connectionpool.py:444\u001b[0m, in \u001b[0;36mHTTPConnectionPool._make_request\u001b[1;34m(self, conn, method, url, timeout, chunked, **httplib_request_kw)\u001b[0m\n\u001b[0;32m 441\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mTypeError\u001b[39;00m:\n\u001b[0;32m 442\u001b[0m \u001b[39m# Python 3\u001b[39;00m\n\u001b[0;32m 443\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[1;32m--> 444\u001b[0m httplib_response \u001b[39m=\u001b[39m conn\u001b[39m.\u001b[39;49mgetresponse()\n\u001b[0;32m 445\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mBaseException\u001b[39;00m \u001b[39mas\u001b[39;00m e:\n\u001b[0;32m 446\u001b[0m \u001b[39m# Remove the TypeError from the exception chain in\u001b[39;00m\n\u001b[0;32m 447\u001b[0m \u001b[39m# Python 3 (including for exceptions like SystemExit).\u001b[39;00m\n\u001b[0;32m 448\u001b[0m \u001b[39m# Otherwise it looks like a bug in the code.\u001b[39;00m\n\u001b[0;32m 449\u001b[0m six\u001b[39m.\u001b[39mraise_from(e, \u001b[39mNone\u001b[39;00m)\n", "File \u001b[1;32mc:\\Python310\\lib\\http\\client.py:1374\u001b[0m, in \u001b[0;36mHTTPConnection.getresponse\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 1372\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[0;32m 1373\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[1;32m-> 1374\u001b[0m response\u001b[39m.\u001b[39;49mbegin()\n\u001b[0;32m 1375\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mConnectionError\u001b[39;00m:\n\u001b[0;32m 1376\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mclose()\n", "File \u001b[1;32mc:\\Python310\\lib\\http\\client.py:318\u001b[0m, in \u001b[0;36mHTTPResponse.begin\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 316\u001b[0m \u001b[39m# read until we get a non-100 response\u001b[39;00m\n\u001b[0;32m 317\u001b[0m \u001b[39mwhile\u001b[39;00m \u001b[39mTrue\u001b[39;00m:\n\u001b[1;32m--> 318\u001b[0m version, status, reason \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_read_status()\n\u001b[0;32m 319\u001b[0m \u001b[39mif\u001b[39;00m status \u001b[39m!=\u001b[39m CONTINUE:\n\u001b[0;32m 320\u001b[0m \u001b[39mbreak\u001b[39;00m\n", "File \u001b[1;32mc:\\Python310\\lib\\http\\client.py:279\u001b[0m, in \u001b[0;36mHTTPResponse._read_status\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 278\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39m_read_status\u001b[39m(\u001b[39mself\u001b[39m):\n\u001b[1;32m--> 279\u001b[0m line \u001b[39m=\u001b[39m \u001b[39mstr\u001b[39m(\u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mfp\u001b[39m.\u001b[39;49mreadline(_MAXLINE \u001b[39m+\u001b[39;49m \u001b[39m1\u001b[39;49m), \u001b[39m\"\u001b[39m\u001b[39miso-8859-1\u001b[39m\u001b[39m\"\u001b[39m)\n\u001b[0;32m 280\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mlen\u001b[39m(line) \u001b[39m>\u001b[39m _MAXLINE:\n\u001b[0;32m 281\u001b[0m \u001b[39mraise\u001b[39;00m LineTooLong(\u001b[39m\"\u001b[39m\u001b[39mstatus line\u001b[39m\u001b[39m\"\u001b[39m)\n", "File \u001b[1;32mc:\\Python310\\lib\\socket.py:705\u001b[0m, in \u001b[0;36mSocketIO.readinto\u001b[1;34m(self, b)\u001b[0m\n\u001b[0;32m 703\u001b[0m \u001b[39mwhile\u001b[39;00m \u001b[39mTrue\u001b[39;00m:\n\u001b[0;32m 704\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[1;32m--> 705\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_sock\u001b[39m.\u001b[39;49mrecv_into(b)\n\u001b[0;32m 706\u001b[0m \u001b[39mexcept\u001b[39;00m timeout:\n\u001b[0;32m 707\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_timeout_occurred \u001b[39m=\u001b[39m \u001b[39mTrue\u001b[39;00m\n", "File \u001b[1;32mc:\\Python310\\lib\\ssl.py:1274\u001b[0m, in \u001b[0;36mSSLSocket.recv_into\u001b[1;34m(self, buffer, nbytes, flags)\u001b[0m\n\u001b[0;32m 1270\u001b[0m \u001b[39mif\u001b[39;00m flags \u001b[39m!=\u001b[39m \u001b[39m0\u001b[39m:\n\u001b[0;32m 1271\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mValueError\u001b[39;00m(\n\u001b[0;32m 1272\u001b[0m \u001b[39m\"\u001b[39m\u001b[39mnon-zero flags not allowed in calls to recv_into() on \u001b[39m\u001b[39m%s\u001b[39;00m\u001b[39m\"\u001b[39m \u001b[39m%\u001b[39m\n\u001b[0;32m 1273\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m\u001b[39m__class__\u001b[39m)\n\u001b[1;32m-> 1274\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mread(nbytes, buffer)\n\u001b[0;32m 1275\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m 1276\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39msuper\u001b[39m()\u001b[39m.\u001b[39mrecv_into(buffer, nbytes, flags)\n", "File \u001b[1;32mc:\\Python310\\lib\\ssl.py:1130\u001b[0m, in \u001b[0;36mSSLSocket.read\u001b[1;34m(self, len, buffer)\u001b[0m\n\u001b[0;32m 1128\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[0;32m 1129\u001b[0m \u001b[39mif\u001b[39;00m buffer \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[1;32m-> 1130\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_sslobj\u001b[39m.\u001b[39;49mread(\u001b[39mlen\u001b[39;49m, buffer)\n\u001b[0;32m 1131\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[0;32m 1132\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_sslobj\u001b[39m.\u001b[39mread(\u001b[39mlen\u001b[39m)\n", "\u001b[1;31mKeyboardInterrupt\u001b[0m: " ] } ], "source": [ "k = 6\n", "AS = AlignmentSearch(dataset=dataset)\n", "query = \"\"\"Say I don't know.\"\"\"\n", "# top_k_sources = AS.get_top_k(query, k)\n", "answer, top_k_sources = AS.search_and_answer(query, k)#, HyDE=True)\n", "print(answer)" ] }, { "cell_type": "code", "execution_count": 153, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Potential impacts of AI range from the immediate and particular to the vast and transformative. While most current scholarly and policy commentary on AI impacts addresses near-term advances and concerns, popular accounts are dominated by vivid scenarios of existential threats to human survival or autonomy, often inspired by fictional accounts in which AI has advanced to general super-intelligence, independent volition, or some other landmark of capabilities equivalent to exceeding those of humans. Expert opinions about the likelihood and timing of such extreme advances vary widely. 2 Yet it is also increasingly clear that such extreme advances in capability are not necessary for AI to have transformative societal impacts—for good or ill, or more likely for both—including the prospect of severe disruptions. Efforts to manage societal impacts of technology always face deep uncertainties, both about trends in technical capabilities and about how they will be used in social context. These perennial challenges are even greater for AI than for other recent areas of technological concern, due to its diffuse, labile character, strong linkages with multiple areas of technological advance, and breadth and diversity of potential application areas. 3 In its foundational and potentially transformative character, AI has been credibly compared to the drivers of previous industrial revolutions, electricity and fossil fuels.\n", " - Title: Max – A Thought Experiment: Could AI Run the Economy Better Than Markets?, Author: Laura Elbaum, Date published: Tue, 11 Feb 2020, URL: https://aipulse.org/max-a-thought-experiment-could-ai-run-the-economy-better-than-markets/\n", "\n", "\n", "\n", "\n", "\n", "Even setting aside “singularity” issues – potential general or super-intelligent AI that might threaten (or in some accounts, transcend) human survival and autonomy – multiple mechanisms of impact have been identified by which even continued development of AI short of these landmarks could have transformative societal impacts. Examples include large-scale displacement of human livelihoods, disruption of geopolitical security relationships, transforming (or undermining) collective decision-making processes through democratic governments or other institutions, extreme concentration of wealth and power (perhaps based on new mechanisms of power), and large-scale changes in human capabilities and identities. Even limiting attention to present and near-term developments, there are a host of concerns raised by current AI applications – e.g., safety and security of systems, bias in algorithmic decision-making, threats to privacy, and inscrutability of decisions – some of which may also give early warning signs of coming larger-scale impacts. Relative to the scale and gravity of potential impacts, present debate on AI and Society presents a seeming paradox. The issue is receiving a flood of attention, with dozens of new programs, a rapid flow of resources, and meetings and conferences seemingly every week.\n", " - Title: Artificial Intelligence’s Societal Impacts, Governance, and Ethics: Introduction to the 2019 Summer Institute on AI and Society and its rapid outputs, Author: Laura Elbaum, Date published: Thu, 26 Sep 2019, URL: https://aipulse.org/artificial-intelligences-societal-impacts-governance-and-ethics-introduction-to-the-2019-summer-institute-on-ai-and-society-and-its-rapid-outputs/\n", "\n", "\n", "\n", "\n", "\n", "It is widely noted, of course, that focusing predominantly on such hypothetical future super-AI risks misleading, by distracting from addressing nearer-term uses and impacts that are also potentially transformative for good or ill – including both the “now” and the mid-term. 3 Technical characteristics, even abstracted from social context, also matter for these near and medium time horizons – i.e., well before development of AGI or super-AI – when AI will clearly have transformative possibilities but still, at least formally, be under human control. The importance of technological characteristics is evident even in current AI controversies, in both what technical capacities allow and what they require. As an example of impacts driven by what technical capacities allow, AI-enabled advances in data integration and surveillance, especially facial recognition, already present significant threats to privacy and autonomy. These capabilities are being deployed because current actors find advantage in them, of course – a matter of social and political context. But it is the technical performance characteristics that create these new capabilities and make them visible. As an example of impacts driven by technical requirements, present machine learning algorithms require training on large labeled datasets. This requirement has driven two powerful effects and points of concern.\n", " - Title: Could AI drive transformative social progress? What would this require?, Author: Laura Elbaum, Date published: Thu, 26 Sep 2019, URL: https://aipulse.org/could-ai-drive-transformative-social-progress-what-would-this-require/\n", "\n", "\n", "\n", "\n", "\n", "In any such settings, we expect the societal impacts and disruptions/transformations of AI, and the associated challenges of governance (indeed, the meaning of governance) to be profoundly transformed, in scale, meaning, and possibly also speed. Yet this is not the singularity. 23 We also distinguish this middle range from existential or singularity-related risks and by the limitation that AI is not self-directed or independently volitional, but rather is still to a substantial degree developed and deployed under human control. Of course, the practical extent of human control in specific applications may be ambiguous, and the details matter a lot. Moreover, as noted above, even with AI not fully autonomous but practically, or formally, under human control, there may still be transformative impacts, including vast public as well as private effects and the potential for large-scale disruptions and harms – in addition to the large benefits that are intended and anticipated. This intermediate range is thick with potential areas and mechanisms of high-stakes AI impacts. In addition to those noted above, involving mechanisms of influence already operating but subject to transformation from increased scale and speed (e.g., livelihood displacement), there are multiple other possibilities. These are substantially more heterogeneous than those already evident in present practice. Even brief reflection suggests a wide range of potential AI applications, impacts, bases for concern, and associated governance challenges. We outline a few below. Many others, similarly plausible, could readily be generated.\n", " - Title: Artificial Intelligence in Strategic Context: an Introduction, Author: Shayda Jalali, Date published: Fri, 08 Feb 2019, URL: https://aipulse.org/artificial-intelligence-in-strategic-context-an-introduction/\n", "\n", "\n", "\n", "\n", "\n", "It has steered many near-term commercial applications toward decision domains such as criminal justice and health, in which huge individual-level datasets with clearly labeled outcomes are available, with little advance consideration of the high personal, legal, and societal stakes – and high costs of error – that are intrinsic to these domains. And it has replicated, by some accounts even magnified, pre-existing biases present in these training data, and projected them forward into future decisions. Our workgroup reflected on the question of AI impacts in broad historical context: in effect, we took seriously the analogy to past technology-fueled revolutionary transformations of human society such as the industrial revolution. But we did this with a perspective opposite to much current debate, considering the prospect for societal impacts that are transformative in scale but beneficial in valence. Speculations about huge societal benefits from AI are common, but tend to be superficial and conclusory, often based on speculative gains in single areas such as medical care or scientific research. By contrast, speculations on AI-driven dystopias are frequent and attention-getting, often with their causal mechanisms characterized in some detail. 4 A Historical Analogy In our inquiry, we drew insight and inspiration from a line of commentary on past societal transformations that gets insufficient attention in current debates on technology impacts – despite being a prominent theme in the work of a few distinguished scholars such as Albert Hirschman and Elizabeth Anderson.\n", " - Title: Could AI drive transformative social progress? What would this require?, Author: Laura Elbaum, Date published: Thu, 26 Sep 2019, URL: https://aipulse.org/could-ai-drive-transformative-social-progress-what-would-this-require/\n", "\n", "\n", "\n", "\n", "\n", "4 In view of these challenges, analysis and criticism of AI’s social impacts and its governance have tended to cluster at two endpoints in terms of the immediacy and scale of the concerns they consider. Most current work targets present or immediately anticipated applications, such as autonomous vehicles and algorithmic decision-support systems in criminal justice, health-care, employment, and education, addressing already present concerns about safety, liability, privacy, bias, and due process. 5 A bolder minority of current work goes to the opposite extreme, aiming to characterize the implications of some future endpoint of capability—super-intelligent AI, or artificial general intelligence (AGI), for example—with attendant risks to human survival or autonomy. This latter work includes efforts to identify and develop technical characteristics that would make AI robustly safe, benign, or “friendly” for humans, no matter how powerful it becomes: in effect, seeking practical (and contradiction-free) analogues to Asimov’s Three Laws of Robotics. 6 The broad range that lies between these two clusters, however—the impacts, risks, and governance challenges of AI that are intermediate in time-scale and magnitude between the immediate and the existential—also carries the potential for transformative societal impacts and disruptions, for good and ill. Yet despite admitting some degree of informed and disciplined speculation, this intermediate range has received less attention.\n", " - Title: Max – A Thought Experiment: Could AI Run the Economy Better Than Markets?, Author: Laura Elbaum, Date published: Tue, 11 Feb 2020, URL: https://aipulse.org/max-a-thought-experiment-could-ai-run-the-economy-better-than-markets/\n", "\n", "\n", "\n", "\n", "\n" ] } ], "source": [ "for source in top_k_sources:\n", " print(source)\n", " print(\"\\n\"*4)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('Context #3 suggests that the limitations on the number of universes that can be real are not yet clear. However, it is suggested that the universe may contain causal bubbles that allow some pieces of spacetime to survive superintelligences appearing in other pieces of spacetime, while the absence of causal bubbles makes it that a superintelligence or collection of superintelligences probably eventually takes over everything.',\n", " [' 2021-11-20\\n\\n ## no room above paperclips\\n\\n (edit: see also [*yes room above paperclips? *](https://carado. moe/above-paperclips-2.\\n\\n when presented with the idea of a [paperclip-maximizing unaligned superintelligence](https://en. wikipedia.org/wiki/Instrumental_convergence#Paperclip_maximizer), people sometimes mention the possibility that sure, the universe gets tiled with paperclips, but maybe there\\'s [slack](https://thezvi. wordpress.com/2017/09/30/slack/) in how paperclips are arranged, and that maybe nice things can exist again \"above\" paperclips.\\n\\n (note: this relates to the idea of [\"daemon-free\"ness in \"minimal circuints\"](https://www.\\n\\n i think it\\'s a reasonable line of thinking, but it\\'s short-sighted: let\\'s think about what happens next. eventually, above those paperclips, some evolutionary process may take place, leading (possibly, such as in our case, through the step of a technological species) eventually to a superintelligence taking over everything. given that *the entire cosmos* gets tiled with paperclips [*possibly forever*](https://carado. moe/ai-alignment-wolfram-physics. html), and that a superintelligent singleton taking over everything is irreversible (short of everything dying forever), in all likelyhood in the long term in any piece of universe not already actively managed by a superintelligence, eventually either everything dies forever, or a superintelligence takes over everything forever.\\n\\n and then what? either this new superintelligence cares about \"upwards\", and has some plan for how its own paperclips are arranged (such as into more \"macro\"-paperclips), or it doesn\\'t and the cycle begins again.\\n\\n given that the outcome of an \"alien\" superintelligence\\'s takeover is probly a worse outcome than the takeover of a superintelligence of our own (we should expect them to be about as incompetent as us at alignment, but to have values [less aligned to ours](https://www. lesswrong.com/posts/HawFh7RvDM4RyoJ2d/three-worlds-collide-0-8)), we need to care about our own iteration first, it\\'s our best bet.\\n - Title: no room above paperclips, Date published: 2021-11-20',\n", " \" 2021-07-18\\n\\n ## AI alignment timeline codes\\n\\n this is a small post proposing simple one-letter codes for identifying timelines depending on their status relative to [AI alignment](https://en. wikipedia.org/wiki/AI_control_problem) and the appearance of [superintelligence](https://en.\\n\\n * **P-line**: a pre-intelligence explosion and pre-figuring out AI alignment timeline. we are in a P-line. * **X-line**: a timeline where an [existential risk (or X-risk)](https://en. wikipedia.org/wiki/X-risk) has been realized by an unaligned superintelligence. everything is dead, forever. * **S-line**: a timeline where a [suffering risk (or S-risk)](https://en. wikipedia.org/wiki/S-risk) has been realized by an unaligned superintelligence; the universe from then on contains net suffering on immense scales for all remaining time, [which is possibly infinite](https://carado. moe/ai-alignment-wolfram-physics. html). we should want to avoid this pretty much at all costs (including by [opting for an X-line instead](https://carado. moe/when-in-doubt-kill-everyone. html)). * **A-line**: AI alignment has been figured out, and no superintelligence has been deployed yet. from that point on, we have the means to reach a U-line; though this isn't guaranteed. this is where we want to get as soon as possible. * **U-line**: an aligned or [somehow otherwise](https://www. lesswrong.com/tag/orthogonality-thesis) benevolent superintelligence has been deployed, and we are guaranteed a relatively utopian world forever. this is the ultimate goal. while not strictly necessary, going through an A-line is almost certainly required to get there.\\n\\n U-line, X-line, and S-line all have deployed superintelligences and are therefore terminal outcomes; they are unescapable. P-line and A-line are transitionary; they likely lead to one of the three terminal outcomes mentioned here.\\n\\n other terminal might exist, but they seem unlikely enough to not warrant listing here; for example, even if everyone dies from, say, a meteor impact, life on earth or nearby will probably evolve another civilization *eventually*, which will also probably face the AI alignment challenge and end up in one of the terminal timelines. \\n\\n \\n - Title: AI alignment timeline codes, Date published: 2021-07-18\",\n", " 'or \"is there a function that can, in time polynomial to `n`, predict a piece of state that would naively take `aⁿ` steps to compute\"?\\n\\n ### 2: does the cosmos instantiate any rich computation ?\\n\\n to **instantiate a computation** means for that computation to, somewhere, eventually, be ran (forever or until it halts). i start from the fact that i\\'m observing a coherent-looking universe, deduce that at least *some* computation is happening, and which other computations are happening (as in, are being observed somewher, or which i could have observed). as [clarified before](https://carado. moe/limiting-real-universes. html), one can\\'t just assume that all computations are equally happening: things look way too coherent for that, there seems to be a bias for coherence/simplicity (one which i\\'ve tentatively attributed to [how soon that computation spawns](https://carado. moe/less-quantum-immortality. html)).\\n\\n looking at the cosmos (the set of instantiated computations) from a computational perspective, it seems like it contains at least our universe, which is expanding. if this expansion is, [as has been hypothesized](https://www. wolframphysics.org/technical-introduction/potential-relation-to-physics/cosmology-expansion-and-singularities/), caused by the computational substrate of the universe manufacturing new vertices of spacetime, and computations can run on this new fabric as it is produced, then it\\'s possible that [some computations can run forever](https://carado. moe/ai-alignment-wolfram-physics. html), including potentially rich ones.\\n\\n however:\\n\\n ### 3: does the cosmos contain causal bubbles ?\\n\\n a **causal bubble** is a piece of computation that can run forever with the guarantee that it won\\'t be physically interfered with from the outside; see [yes room above paperclips](https://carado. moe/above-paperclips-2. html).\\n\\n for example, while one can build [a turing machine inside conway\\'s game of life](https://www. conwaylife.com/wiki/Turing_machine), a stray object on the same conway\\'s game of life plane can eventually collide with said machine and break its computational process.\\n - Title: questions about the cosmos and rich computations, Date published: 2022-01-07',\n", " ' however, in some [graph rewriting rulesets](https://en. wikipedia.org/wiki/Graph_rewriting), as well as in expression-rewriting systems with nested expressions such as a varient of [SKI calculus](https://en. wikipedia.org/wiki/SKI_combinator_calculus) or [lambda calculus](https://en. wikipedia.org/wiki/Λ_calculus) where the evaluation rule expands all sub-expressions, some pieces of computation can run without ever being physically interfered with by other pieces of the computation.\\n\\n (i\\'m specifying \"*physically* interfered with\" because acausal coordination or mutual simulation can lead to interference, but at least that interference is up to the singleton (such as a superintelligence) \"running\" said bubble (if any); they can just choose to never acausally coordinate and to never simulate other bubbles)\\n\\n in our own spacetime, it seems like causal bubbles exist thanks to the expansion of spacetime: some pairs of points get further apart from one another faster than celerity, and thus should never be able to interact with one another so long as that expansion continues and FTL travel is impossible. under the perspective of wolfram physics, however, it is not clear that both of those things will necessarily be the case forever; spacetime might be [hackable](https://carado. moe/brittle-physics. html).\\n\\n note that the splitting of universes with nondeterministic rules (such as ours with quantum mechanics) into different causally isolated timelines is another way for causal bubbles to exist, assuming the implementation of such a nondeterministic universe is that all possibilities are instantiated at any nondeterministic choice.\\n\\n the presence of causal bubbles allows some pieces of spacetime to [survive superintellingences appearing in other pieces of spacetime](https://carado. moe/unoptimal-superint-doesnt-lose. html), while the absence of causal bubbles makes it that a superintelligence or collection of superintelligences probably eventually does take over everything.\\n\\n if they exist, then causal bubbles are a blessing and a curse: they save us from alien superintelligences and, [between timelines](https://carado. moe/timeline-codes. html), from our own superintelligences, but they might also ensure that our own aligned superintelligence (once we have figured out alignment) cannot reach all computation, and thus that any random person has a good chance of existing in a bubble that hasn\\'t been \"saved\" by our aligned superintelligence.\\n - Title: questions about the cosmos and rich computations, Date published: 2022-01-07',\n", " \"/2020/04/finally-we-may-have-a-path-to-the-fundamental-theory-of-physics-and-its-beautiful/) is a project by [stephen wolfram](https://www. youtube.com/watch? v=0bMYtEKjHs0) to model physics using something kind of like a cellular automaton made of vertices in a graph instead of cells on a grid.\\n\\n it's pretty interesting and there are insights in and around it that are of importance for the far future, and thus for [AI alignment](https://carado. moe/were-all-doomed. html).\\n\\n the most notable is that wolfram thinks there's compute everywhere. the motion of the wind is doing compute, the motion of the seas is doing compute, the fabric of spacetime is doing compute, and even the state of heat death is still doing compute.\\n\\n that last point notably means we might be able to embed ourselves into heat death and further, and thus get computed literally forever. this multiplies the importance of AI alignment by potentially literally infinity. i'm not quite sure how we are to handle this.\\n\\n some of the compute may be doing things that are opaque to us; it might appear [homomorphically encrypted](https://en. wikipedia.org/wiki/Homomorphic_encryption). as we want (and expect) our superintelligence to spread everywhere to enforce values, we would hope civilizations living inside homomorphically encrypted spaces can be inspected; otherwise, nuking them altogether might be the only way to ensure that no [S-risk](https://en. wikipedia.org/wiki/Suffering_risks) is happening there.\\n\\n wolfram postulates that one might be able to hack into the fabric of spacetime; one of the mildest effects of this would be the ability to communicate (and thus, likely, move) faster than celerity (but probably still slower than some other hard limit). if you didn't think [AI boxing](https://en. wikipedia.org/wiki/AI_box) was hopeless enough as it is, hackable spacetime ought to convince you.\\n\\n finally, there is, value wise, an immense amount of compute being wasted; even just [standard model particles](https://en. wikipedia.org/wiki/Standard_Model) live way above true elementary computation. if superintelligence is well-aligned, this provides us with an hard estimate as to how much computing power we can live on to enjoy value, and it's probably a very large amount; wolfram [talks about](https://writings.stephenwolfram.com/2020/04/finally-we-may-have-a-path-to-the-fundamental-theory-of-physics-and-its-beautiful#how-it-works) something like 1e400 vertices in our universe.\\n\\n \\n - Title: AI alignment and wolfram physics, Date published: 2021-07-17\",\n", " '/musks-non-missing-mood/) that resonates quite well with me. it is indeed kind of disconcerting how people who seem rationally aware of AI risk, don\\'t seem to *grok* it as an *actual thing*. despite how real it is, it\\'s hard to think of it not as fantasy fiction.\\n\\n i totally understand why. i\\'ve been there too. but eventually i managed to progressively update.\\n\\n i\\'m still not quite there yet, but i\\'m starting to actually grasp what is at stake.\\n\\n [\"detaching the grim-o-meter\"](https://mindingourway.com/detach-the-grim-o-meter/) remains a reasonable thing to do; you don\\'t want to become so depressed that you kill yourself instead of saving the world. but you also don\\'t want to remain so deluded that you don\\'t quite weigh the importance of saving the world enough either.\\n\\n i\\'ll learn japanese after the singularity. i\\'ll make [my game](https://carado. moe/game. html) and [my alternative web](https://carado. moe/saving-the-web. html) and my conlang and [my software stack](https://carado. moe/psi. html) and many other things, after the singularity. it is painful. but it is what\\'s right; it\\'s closer to [the best i can do](https://www. lesswrong.com/posts/j9Q8bRmwCgXRYAgcJ/miri-announces-new-death-with-dignity-strategy).\\n\\n and i know that, if at some point i give up, then it won\\'t look like pretending that everything is fine and compartmentalizing our imminent death as some fantasy scenario. it\\'ll be a *proper* giving up, like going to spend the remaining years of my life with my loved ones. even my giving up scenario is one that takes things seriously, as it should. that\\'s what being an adult capable of taking things seriously is like. how you handle your mental state is up to you. there is a collection of AI-risk-related mental health posts [here](https://www. lesswrong.com/posts/pLLeGA7aGaJpgCkof/mental-health-and-the-alignment-problem-a-compilation-of). do what it takes for you to do the work that needs to be done. that\\'s not becoming a doomer; your brain is straight-up not designed to deal with cosmic doom. but that\\'s not remaining blindly naive either. the world needs you; it won\\'t be saved by pretending things are fine.\\n\\n and it *certainly* won\\'t be saved by pretending things are fine and *working on AI capability*. that\\'s *just bad*. *please* don\\'t.\\n\\n please take AI risk seriously.\\n\\n \\n - Title: life refocus, Date published: 2022-05-13',\n", " \" 2021-03-04\\n\\n ## Value Crystallization\\n\\n there is a weird phenomenon whereby, as soon as an agent is rational, it will want to conserve its current values, as that is in general the most sure way to ensure it will be ablo to start achieving those values.\\n\\n however, the values themselves aren't, and in fact [cannot](https://en. wikipedia.org/wiki/Is–ought_problem) be determined purely rationally; rationality can at most help [investigate](https://carado. moe/core-vals-exist-selfdet. html) what values one has.\\n\\n given this, there is a weird effect whereby one might strategize about when or even if to inform other people about [rationality](https://www. readthesequences.com/) at all: depending on when this is done, whichever values they have at the time might get crystallized forever; whereas otherwise, without an understanding of why they should try to conserve their value, they would let those drift at random (or more likely, at the whim of their surroundings, notably friends and market forces).\\n\\n for someone who hasn't thought about values much, *even just making them wonder about the matter of values* might have this effect to an extent.\\n\\n \\n - Title: Value Crystallization, Date published: 2021-03-04\",\n", " \" 2021-10-23\\n\\n ## alignment is an optimization processes problem\\n\\n i like to talk about [AI](https://www. lesswrong.com/tag/ai) alignment a lot, but the matter of alignment is really general to *optimization processes* in general.\\n\\n here are some ways it applies to some other areas:\\n\\n ### natural selection\\n\\n natural selection is an optimization process that improves the survival and duplication of inheritable traits (genes) in living beings.\\n\\n it is not intelligent: there is no agent involved in this process which is able to make decisions by looking ahead into the future at what consequences those decisions will have; with the possible exception of humans making rational decisions about what will maximize their amount offspring.\\n\\n it is completely multipolar: basically no agents in this process (either genes themselves, or individuals or populations carrying those genes) have the ability to coordinate decisions with one another, since they're not even intelligent.\\n\\n the default of natural selection is genes whose only purpose is to be better at duplicating themseles.\\n\\n one way in which we've aligned this process is by breeding: by selecting the individuals we like best among, for example, crops, cattle, or dogs, we've been able to align the process of gene selection to respond to what we value rather than the default.\\n\\n ### economics\\n\\n the economy is an optimization process that improves economic efficiency.\\n\\n it is intelligent: actors in the economy, ranging from individuals to states and giant conglomerates, have the ability to make intelligent decisions about the long term.\\n\\n it is fairly multipolar: while they don't use it much, states do have overriding power over companies (they determine what's legal or not, after all), and also economic agents are able to coordinate to an extent using contracts and trusts. nevertheless, it is still largely multipolar, with agents overall competing with one another.\\n\\n the default of economics is the optimization out of anything that doesn't generate maximally much resources: the optimizing out of people when they become the unoptimal form of labor because of automation, and the strip-mining of the universe to acquire ever more resources with which to create more machines to mine even more resources, and so on.\\n\\n the way we align economics is through taxes, redistribution, and the like. redistribution like [UBI](https://carado. moe/ubi. html) aligns the economy to serves the demand of people, while tax externalities can align economic agents to take steps to preserve nice things, such as avoiding pollution.\\n - Title: alignment is an optimization processes problem, Date published: 2021-10-23\",\n", " \" 2021-06-30\\n\\n ## we're all doomed\\n\\n [a major tech company is now explicitly invested in getting AI to write code](https://copilot. github.com/).\\n\\n this is a major warning sign; a first step on the explicit path to [superintelligence](https://en. wikipedia.org/wiki/Superintelligence) [explosion](https://en. wikipedia.org/wiki/Technological_singularity#Intelligence_explosion), an event [already considered relatively likely](https://intelligence.org/faq/#imminent) and, [in the absence of sufficient AI alignment progress](https://intelligence.org/2018/10/03/rocket-alignment/), is overwhelmingly likely to [permanently end all life at least in the observable universe](https://en. wikipedia.org/wiki/Instrumental_convergence#Paperclip_maximizer).\\n\\n the time scale probably lies somewhere between a few years and a few decades, but in any case it's becoming to seem increasingly unlikely that [the only organization trying to actually figure out AI alignment](https://intelligence.org/) is gonna accomplish that in time.\\n\\n if you can, go and [help them out](https://intelligence.org/get-involved/), or at least [donate everything you can to them](https://intelligence.org/donate/).\\n\\n if you're currently working in AI development in any way, *please stop*. whether anything on earth survives this century is gonna be a matter of whether AI alignment is figured out by the time we get enough AI development; by helping the latter, you're making it even more likely that it happens before the former.\\n\\n on a gloomier note, if you have all the philosophical beliefs required to think it can work, you may want to start preparing to [abandon this timeline](https://carado. moe/quantum-suicide. html) if singularity starts happening and looks like it's not gonna go well.\\n\\n edit: see also: [are we in an AI overhang? ](https://www.\\n\\n \\n - Title: we're all doomed, Date published: 2021-06-30\",\n", " ' 2022-03-21\\n\\n ## values system as test-driven development\\n\\n i realized something while reading [hands and cities on infinite ethics](https://handsandcities.com/2022/01/30/on-infinite-ethics/): the work of determining the shape of [our values system](https://carado. moe/not-hold-on-to-values. html) is akin to [test-driven development](https://en. wikipedia.org/wiki/Test-driven_development).\\n\\n we are designing a procedure (possibly looking for [the simplest one](https://en. wikipedia.org/wiki/Kolmogorov_complexity)) by throwing it at a collection of decision tests, and looking for which one matches our intuitions.\\n\\n i wonder if a value-learning approach to AI alignment could look like trying to get superintelligence to find such a procedure; perhaps we feed it a collection of tests and it looks for the simplest procedure that matches those, and hopefully that extrapolates well to situations we didn\\'t think of.\\n\\n perhaps, even pre-superintelligence we can formalize values research as tests and try to come up with or generate a simple procedure which passes them while also being selected for simplicity.\\n\\n why simplicity? doesn\\'t occam\\'s razor only apply to descriptive research, not prescriptive? that is true, but \"what is the procedure that formalizes my values system\" is indeed a prescriptive matter, in a way: we\\'re trying to model something to the best factual accuracy we can.\\n\\n \\n - Title: values system as test-driven development, Date published: 2022-03-21'])" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "answer" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "## Tests" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Comparing quantity of articles/words/tokens/characters in the official dataset vs. what we have" ] }, { "cell_type": "code", "execution_count": 158, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Source Truth Empirical Difference\n", "https://aipulse.org 23 23 0 \n", "manual ? 1 UNKNOWN \n", "waitbutwhy.com 2 2 0 \n", "https://vkrakovna.wo 43 43 0 \n", "https://jsteinhardt. 39 39 0 \n", "https://aisafety.cam 8 8 0 \n", "curriculum ? 1 UNKNOWN \n", "https://www.yudkowsk 23 23 0 \n", "\n", " Truth Empirical Difference\n", "Word Count 53550146 335374 53214772 \n", "Character Count 351767163 2096402 349670761 \n" ] } ], "source": [ "num_articles_truth = {\n", " 'https://aipulse.org': 23,\n", " 'ebook': 23,\n", " 'https://qualiacomputing.com': 278,\n", " 'alignment forum': 2138,\n", " 'lesswrong': 28252 + 227,\n", " 'manual': \"?\",\n", " 'arxiv': 707 + 1679 + 1000 + 4621,\n", " 'https://deepmindsafetyresearch.medium.com/': 10,\n", " 'waitbutwhy.com': 2,\n", " 'GitHub': \"?\",\n", " 'https://aiimpacts.org': 227,\n", " 'arbital.com': 223,\n", " 'carado.moe': 59,\n", " 'nonarxiv_papers': \"?\",\n", " 'https://vkrakovna.wordpress.com': 43,\n", " 'https://jsteinhardt.wordpress.com': 39,\n", " 'audio-transcripts': 25 + 12,\n", " 'https://intelligence.org': 479,\n", " 'youtube': 457,\n", " 'reports': \"?\",\n", " 'https://aisafety.camp': 8,\n", " 'curriculum': \"?\",\n", " 'https://www.yudkowsky.net': 23,\n", " 'distill': 49,\n", " 'total': 2138+28252+707+1679+1000+4621+23+227+23+8+59+111+10+17+7+479+39+278+43+2+23+420+323+49+457+25+12+223+227+132 \n", "}\n", "word_count_truth = 53_550_146\n", "char_count_truth = 351_767_163\n", "\n", "# Print table. First row has Truth and Empirical findings.\n", "print(f\"{'Source':<20} {'Truth':<10} {'Empirical':<10} {'Difference':<10}\")\n", "for source in dataset.articles_count:\n", " try:\n", " print(f\"{source[:20]:<20} {num_articles_truth[source]:<10} {dataset.articles_count[source]:<10} {num_articles_truth[source] - dataset.articles_count[source]:<10}\")\n", " except TypeError:\n", " print(f\"{source[:20]:<20} {num_articles_truth[source]:<10} {dataset.articles_count[source]:<10} {'UNKNOWN':<10}\")\n", "\n", "# Compare true and empirical word counts and character counts\n", "print(f\"\\n{'':<20} {'Truth':<10} {'Empirical':<10} {'Difference':<10}\")\n", "print(f\"{'Word Count':<20} {word_count_truth:<10} {dataset.total_word_count:<10} {word_count_truth - dataset.total_word_count:<10}\")\n", "print(f\"{'Character Count':<20} {char_count_truth:<10} {dataset.total_char_count:<10} {char_count_truth - dataset.total_char_count:<10}\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Embeeding time estimation" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Define a helper function that takes in a single string and outputs a single d-dimensional vector\n", "def get_embedding(text):\n", " # Use the embeddings OpenAI API endpoint to get an embedding for the text\n", " result = openai.Embedding.create(model=EMBEDDING_MODEL, input=text)\n", " # Convert the response to a numpy array and return it\n", " return result[\"data\"][0][\"embedding\"]\n", "\n", "# Define a function that takes in a list of strings and outputs a numpy matrix of embeddings\n", "def get_embeddings(texts):\n", " embeddings = []\n", " with concurrent.futures.ThreadPoolExecutor() as executor:\n", " futures = [executor.submit(get_embedding, text) for text in texts]\n", " for future in concurrent.futures.as_completed(futures):\n", " embeddings.append(future.result())\n", " return np.vstack(embeddings)\n", "\n", "def get_embeddings_not_parallel(texts):\n", " embeddings = np.array([get_embedding(text) for text in texts])\n", " return embeddings" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Regular method: 23.137897491455078\n", "Parallel method: 1.7662100791931152\n", "(100, 1536)\n", "(100, 1536)\n" ] } ], "source": [ "# Define a list of texts to be embedded\n", "texts = [\"Hello world!\"] * 100\n", "\n", "# Regular method\n", "start = time.time()\n", "embeddings_1 = get_embeddings_not_parallel(texts)\n", "end = time.time()\n", "print(f\"Regular method: {end - start}s\")\n", "\n", "# Parallel method\n", "start = time.time()\n", "embeddings_2 = get_embeddings(texts)\n", "end = time.time()\n", "print(f\"Parallel method: {end - start}s\")" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "Conclusion: async method is ~10x faster than sync method" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Streaming ChatGPT response" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import asyncio\n", "import config\n", "import openai\n", "openai.api_key = config.OPENAI_API_KEY" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "ename": "RuntimeError", "evalue": "asyncio.run() cannot be called from a running event loop", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mRuntimeError\u001b[0m Traceback (most recent call last)", "Cell \u001b[1;32mIn[2], line 24\u001b[0m\n\u001b[0;32m 22\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39m__name__\u001b[39m \u001b[39m==\u001b[39m \u001b[39m'\u001b[39m\u001b[39m__main__\u001b[39m\u001b[39m'\u001b[39m:\n\u001b[0;32m 23\u001b[0m question \u001b[39m=\u001b[39m \u001b[39m\"\u001b[39m\u001b[39mWhat is the Natural Abstraction Hypothesis?\u001b[39m\u001b[39m\"\u001b[39m\n\u001b[1;32m---> 24\u001b[0m asyncio\u001b[39m.\u001b[39;49mrun(test_stream(question))\n", "File \u001b[1;32mc:\\Python310\\lib\\asyncio\\runners.py:33\u001b[0m, in \u001b[0;36mrun\u001b[1;34m(main, debug)\u001b[0m\n\u001b[0;32m 9\u001b[0m \u001b[39m\"\"\"Execute the coroutine and return the result.\u001b[39;00m\n\u001b[0;32m 10\u001b[0m \n\u001b[0;32m 11\u001b[0m \u001b[39mThis function runs the passed coroutine, taking care of\u001b[39;00m\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 30\u001b[0m \u001b[39m asyncio.run(main())\u001b[39;00m\n\u001b[0;32m 31\u001b[0m \u001b[39m\"\"\"\u001b[39;00m\n\u001b[0;32m 32\u001b[0m \u001b[39mif\u001b[39;00m events\u001b[39m.\u001b[39m_get_running_loop() \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[1;32m---> 33\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mRuntimeError\u001b[39;00m(\n\u001b[0;32m 34\u001b[0m \u001b[39m\"\u001b[39m\u001b[39masyncio.run() cannot be called from a running event loop\u001b[39m\u001b[39m\"\u001b[39m)\n\u001b[0;32m 36\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m coroutines\u001b[39m.\u001b[39miscoroutine(main):\n\u001b[0;32m 37\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mValueError\u001b[39;00m(\u001b[39m\"\u001b[39m\u001b[39ma coroutine was expected, got \u001b[39m\u001b[39m{!r}\u001b[39;00m\u001b[39m\"\u001b[39m\u001b[39m.\u001b[39mformat(main))\n", "\u001b[1;31mRuntimeError\u001b[0m: asyncio.run() cannot be called from a running event loop" ] } ], "source": [ "import asyncio\n", "\n", "async def test_stream(question: str):\n", " assistant_prompt = \"You are a helpful assistant, and you help users by answering questions and providing information about AI Alignment, on which you are extremely knowledgeable. Answer the user's question even if you are not certain of the answer; it is supremely important that you do attempt to offer an answer related to the user's query.\"\n", " \n", " messages = [\n", " {\"role\": \"system\", \"content\": assistant_prompt},\n", " {\"role\": \"user\", \"content\": question},\n", " ]\n", " async for part in await openai.ChatCompletion.acreate(\n", " model=COMPLETIONS_MODEL,\n", " messages=messages,\n", " stream=True\n", " ):\n", " finish_reason = part[\"choices\"][0][\"finish_reason\"]\n", " if \"content\" in part[\"choices\"][0][\"delta\"]:\n", " content = part[\"choices\"][0][\"delta\"][\"content\"]\n", " print(content, end=\"\")\n", " elif finish_reason:\n", " print(finish_reason)\n", "\n", "if __name__ == '__main__':\n", " question = \"What is the Natural Abstraction Hypothesis?\"\n", " asyncio.run(test_stream(question))" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "### Tiktoken-related tests" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import tiktoken\n", "encoding = tiktoken.get_encoding(\"cl100k_base\")\n", "encoding.encode(\"tiktoken is great!\")\n", "\n", "def num_tokens_from_string(string: str, encoding_name: str) -> int:\n", " \"\"\"Returns the number of tokens in a text string.\"\"\"\n", " encoding = tiktoken.get_encoding(encoding_name)\n", " num_tokens = len(encoding.encode(string))\n", " return num_tokens\n", "\n", "a = num_tokens_from_string(\"tiktoken is great!\", \"cl100k_base\")\n", "print(a)\n", "# Output: 6\n", "\n", "def num_tokens_from_messages(messages, model=\"gpt-3.5-turbo-0301\"):\n", " \"\"\"Returns the number of tokens used by a list of messages.\"\"\"\n", " try:\n", " encoding = tiktoken.encoding_for_model(model)\n", " except KeyError:\n", " encoding = tiktoken.get_encoding(\"cl100k_base\")\n", " except AttributeError:\n", " encoding = tiktoken.get_encoding(\"cl100k_base\")\n", " if model == \"gpt-3.5-turbo-0301\": # note: future models may deviate from this\n", " num_tokens = 0\n", " for message in messages:\n", " num_tokens += 4 # every message follows {role/name}\\n{content}\\n\n", " for key, value in message.items():\n", " num_tokens += len(encoding.encode(value))\n", " if key == \"name\": # if there's a name, the role is omitted\n", " num_tokens += -1 # role is always required and always 1 token\n", " num_tokens += 2 # every reply is primed with assistant\n", " return num_tokens\n", " else:\n", " raise NotImplementedError(f\"\"\"num_tokens_from_messages() is not presently implemented for model {model}.\n", "See https://github.com/openai/openai-python/blob/main/chatml.md for information on how messages are converted to tokens.\"\"\")\n", "b = num_tokens_from_messages([{\"name\": \"user\", \"content\": \"hello\"}], model=\"gpt-3.5-turbo-0301\")\n", "print(b)\n", "# Output: 7" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "tiktoken is a great library to work with tokens in text!\n" ] } ], "source": [ "import tiktoken\n", "\n", "def limit_tokens(text: str, max_tokens: int, encoding_name: str = \"cl100k_base\") -> str:\n", " encoding = tiktoken.get_encoding(encoding_name)\n", " tokens = encoding.encode(text)[:max_tokens]\n", " return encoding.decode(tokens)\n", "\n", "# Example usage\n", "input_text = \"tiktoken is a great library to work with tokens in text!\"\n", "limited_text = limit_tokens(input_text, 1000)\n", "print(limited_text)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "import pinecone\n", "import config\n", "PINECONE_API_KEY = config.PINECONE_API_KEY\n", "\n", "pinecone.init(api_key=PINECONE_API_KEY, environment=\"us-central1-gcp\")" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['quickstart']" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "pinecone.create_index(\"quickstart\", dimension=8, metric=\"euclidean\", pod_type=\"p1\")\n", "pinecone.list_indexes()\n", "# Returns:\n", "# ['quickstart']" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "index = pinecone.Index(\"quickstart\")" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'upserted_count': 5}" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Upsert sample data (5 8-dimensional vectors)\n", "index.upsert([\n", " (\"A\", [0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]),\n", " (\"B\", [0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2]),\n", " (\"C\", [0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3]),\n", " (\"D\", [0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4]),\n", " (\"E\", [0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5])\n", "])" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'dimension': 8,\n", " 'index_fullness': 0.0,\n", " 'namespaces': {'': {'vector_count': 5}},\n", " 'total_vector_count': 5}" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "index.describe_index_stats()\n", "# Returns:\n", "# {'dimension': 8, 'index_fullness': 0.0, 'namespaces': {'': {'vector_count': 5}}}" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'matches': [{'id': 'C',\n", " 'score': 0.0,\n", " 'values': [0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3]},\n", " {'id': 'D',\n", " 'score': 0.0799999237,\n", " 'values': [0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4]},\n", " {'id': 'B',\n", " 'score': 0.0800000429,\n", " 'values': [0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2]}],\n", " 'namespace': ''}" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "index.query(\n", " vector=[0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3],\n", " top_k=3,\n", " include_values=True\n", ")\n", "# Returns:\n", "# {'matches': [{'id': 'C',\n", "# 'score': 0.0,\n", "# 'values': [0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3]},\n", "# {'id': 'D',\n", "# 'score': 0.0799999237,\n", "# 'values': [0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4]},\n", "# {'id': 'B',\n", "# 'score': 0.0800000429,\n", "# 'values': [0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2]}],\n", "# 'namespace': ''}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pinecone.delete_index(\"quickstart\")" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.6" }, "orig_nbformat": 4, "vscode": { "interpreter": { "hash": "369f2c481f4da34e4445cda3fffd2e751bd1c4d706f27375911949ba6bb62e1c" } } }, "nbformat": 4, "nbformat_minor": 2 }