Files
stampy-chat/src/testing.ipynb
T

139 KiB

Testing

source: this key separates the various keys found in the table in Sources. Here's the set of sources with their corresponding value name:

'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'

...and this is how the arxiv papers look like:

{
    "source": "arxiv", # where the dataset comes from
    "source_type": "latex", # the type of file the data was original in
    "converted_with": "pandoc", # which tool we used to convert the data in .md format
    "paper_version": paper_id,
    "title": title,
    "authors": [str(x) for x in authors], # list of authors
    "date_published": date_published,
    "data_last_modified": data_last_modified,
    "url": url,
    "abstract": abstract,
    "author_comment": author_comment,
    "journal_ref": journal_ref,
    "doi": doi,
    "primary_category": primary_category,
    "categories": categories,
    "citation_level": citation_level, # (0 = curated alignment papers, 1 = citation of curated papers, 2 = citation of citation, etc.)
    "alignment_text": is_alignment_text, # 'pos' is maunally labeled as an alignment paper, 'unlabeled' if unlabeled
    "confidence_score": confidence_scores, # this is a confidence score obtained by using the SPECTER model to classify papers to add to the dataset
    "main_tex_filename": "main.tex", # the main latex file needed to convert the paper
    "text": "lots of text", # this is where you will grab the text contents of each entry in the dataset (in .md format)
    "bibliography_bbl": "string of bbl",
    "bibliography_bib": "string of bib", # more common to have bib than bbl
}

Imports

In [2]:
import jsonlines
import numpy as np
from typing import List, Dict, Tuple, DefaultDict, Any
import re
import time
import random
import pickle
import openai
import concurrent.futures
from tenacity import (
    retry,
    stop_after_attempt,
    wait_random_exponential,
)  # for exponential backoff
import tiktoken

import config
from pathlib import Path
from collections import defaultdict
In [3]:
# FROM https://stackoverflow.com/a/31505798/16185542
# -*- coding: utf-8 -*-
alphabets= "([A-Za-z])"
prefixes = "(Mr|St|Mrs|Ms|Dr)[.]"
suffixes = "(Inc|Ltd|Jr|Sr|Co)"
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)"
acronyms = "([A-Z][.][A-Z][.](?:[A-Z][.])?)"
websites = "[.](com|net|org|io|gov|edu|me)"
digits = "([0-9])"

def split_into_sentences(text):
    text = " " + text + "  "
    text = text.replace("\n"," ")
    text = text.replace("?!", "?")
    text = re.sub(prefixes,"\\1<prd>",text)
    text = re.sub(websites,"<prd>\\1",text)
    text = re.sub(digits + "[.]" + digits,"\\1<prd>\\2",text)
    if "..." in text: text = text.replace("...","<prd><prd><prd>")
    if "Ph.D" in text: text = text.replace("Ph.D.","Ph<prd>D<prd>")
    text = re.sub("\s" + alphabets + "[.] "," \\1<prd> ",text)
    text = re.sub(acronyms+" "+starters,"\\1<stop> \\2",text)
    text = re.sub(alphabets + "[.]" + alphabets + "[.]" + alphabets + "[.]","\\1<prd>\\2<prd>\\3<prd>",text)
    text = re.sub(alphabets + "[.]" + alphabets + "[.]","\\1<prd>\\2<prd>",text)
    text = re.sub(" "+suffixes+"[.] "+starters," \\1<stop> \\2",text)
    text = re.sub(" "+suffixes+"[.]"," \\1<prd>",text)
    text = re.sub(" " + alphabets + "[.]"," \\1<prd>",text)
    if "" in text: text = text.replace(".”","”.")
    if "\"" in text: text = text.replace(".\"","\".")
    if "!" in text: text = text.replace("!\"","\"!")
    if "?" in text: text = text.replace("?\"","\"?")
    text = text.replace(".",".<stop>")
    text = text.replace("?","?<stop>")
    text = text.replace("!","!<stop>")
    text = text.replace("<prd>",".")

    sentences = text.split("<stop>")
    sentences = sentences[:-1]
    sentences = [s.strip() for s in sentences]
    
    if sentences == []:
        sentences = [text.strip()]
    return sentences


class TokenSplitter:
    """splits text into blocks of tokens according to chatgpt's tokenizer"""
    def __init__(self, min_tokens: int = 500, max_tokens: int = 750):
        self.encoding = tiktoken.get_encoding("cl100k_base")
        self.min_tokens = min_tokens
        self.max_tokens = max_tokens
        self.blocks = []
        self.signature = "{url, title, author} unknown"
        


    def _text_splitter(self, text: str) -> List[str]:
        """splits text into blocks of tokens according to chatgpt's tokenizer"""
        # Do not call this function outside of split()      
        
        enc = self.encoding.encode # takes a string and returns a list of ints (tokens)
        dec = self.encoding.decode # takes a list of ints (tokens) and returns a string
        tok_len = lambda x: len(enc(x)) # length of a string in tokens

        max_tokens = self.max_tokens - tok_len(self.signature) - 10 # 10 to be safe
        assert max_tokens > 0, "max_tokens is too small for the signature"
        
        min_tokens = self.min_tokens - tok_len(self.signature) - 10 # 10 to be safe
        assert min_tokens > 0, "min_tokens is too small for the signature"

        current_block = ""
        paragraphs = text.split("\n\n")
        for paragraph in paragraphs:
            sentences = split_into_sentences(paragraph)
            if current_block != "":
                current_block += "\n\n"

            for sentence in sentences:
                potential_new_block = current_block + " " + sentence
                
                if tok_len(potential_new_block) <= max_tokens:
                    current_block = potential_new_block
                
                else:
                    self.blocks.append(current_block)
                    if tok_len(sentence) < max_tokens:
                        current_block = sentence
                    else:
                        self.blocks.append(dec(enc(sentence)[:max_tokens]))
                        current_block = ""
            
            if tok_len(current_block) > min_tokens:
                self.blocks.append(current_block)
                current_block = ""

        if current_block != "":
            if len(self.blocks) == 0:
                self.blocks.append(current_block)
                return
            latest_block = self.blocks[-1]
            len_cur_block = tok_len(current_block)
            latest_plus_current = latest_block + current_block

            if len_cur_block > min_tokens:
                self.blocks.append(current_block)
            
            else:
                #select the last self.max_tokens tokens from the latest block
                last_block = dec(enc(latest_plus_current)[-max_tokens:])
                self.blocks.append(last_block)

        
    
    def split(self, text: str, signature: str) -> List[str]:
        self.signature = signature
        self._text_splitter(text)
        blocks = self.blocks
        self.blocks = []
        self.signature = "{url, title, author} unknown"
        
        # check all block elements are strings
        assert all([isinstance(block, str) for block in blocks]), "block elements are not strings"

        output = [f"{block}\n - {signature}" for block in blocks]
        #check all output elements are strings
        assert all([isinstance(block, str) for block in output]), "output elements are not strings"

        return output

Constants

In [11]:
LEN_EMBEDDINGS = 1536

COMPLETIONS_MODEL = "gpt-3.5-turbo"
EMBEDDING_MODEL = "text-embedding-ada-002"

openai.api_key = config.OPENAI_API_KEY


project_path = Path.cwd().parent # .cwd() returns the current working directory, 
# but in a notebook it is the directory of the notebook. So we need to go up two levels.
PATH_TO_DATA = project_path / "src" / "data" / "alignment_texts.jsonl" # Path to the dataset .jsonl file.
PATH_TO_EMBEDDINGS = project_path / "src" / "data" / "embeddings.npy" # Path to the saved embeddings (.npy) file.
PATH_TO_DATASET = project_path / "src" / "data" / "dataset.pkl" # Path to the saved dataset (.pkl) file.

Helpers

In [6]:
class MissingDataException(Exception):
    pass

Dataset Class

In [129]:
error_count_dict = {
    "Entry has no source.": 0,
    "Entry has no title.": 0,
    "Entry has no text.": 0,
    "Entry has no URL.": 0,
    "Entry has wrong citation level.": 0
}

class Dataset:
    def __init__(self,
            jsonl_data_path: str,  # Path to the dataset .jsonl file.
            custom_sources: List[str] = None,  # List of sources to include, like "alignment forum", "lesswrong", "arxiv",etc.
            rate_limit_per_minute: int = 3_500,  # Rate limit for the OpenAI API.
            min_tokens_per_block: int = 400, # Minimum number of tokens per block.
            max_tokens_per_block: int = 600, # Maximum number of tokens per block.
            fraction_of_articles_to_use: float = 1.0,  # Fraction of articles to use. If 1.0, use all articles.
        ):
        self.jsonl_data_path = jsonl_data_path
        self.custom_sources = custom_sources
        self.rate_limit_per_minute = rate_limit_per_minute
        self.delay_in_seconds = 60.0 / self.rate_limit_per_minute
        self.fraction_of_articles_to_use = fraction_of_articles_to_use
        
        self.min_tokens_per_block = min_tokens_per_block  # for the text splitter
        self.max_tokens_per_block = max_tokens_per_block  # for the text splitter
        
        self.metadata: List[Tuple[str]] = []  # List of tuples, each containing the title of an article, its URL, and text. E.g.: [('title', 'url', 'text'), ...]
        self.embedding_strings: List[str] = []  # List of strings, each being a few paragraphs from a single article (not exceeding 1000 words).
        
        self.articles_count: DefaultDict[str, int] = defaultdict(int)  # Number of articles per source. E.g.: {'source1': 10, 'source2': 20, 'total': 30}

        if self.custom_sources is not None:
            for source in self.custom_sources:
                self.articles_count[source] = 0
        self.total_articles_count = 0
        
        self.total_char_count = 0
        self.total_word_count = 0
        self.total_sentence_count = 0
        self.total_block_count = 0
        
        self.sources_so_far: List[str] = []
        self.info_types: Dict[str, List[str]] = {}
    
    def extract_info_from_article(self, article: Dict[str, Any]) -> Tuple[str]:
        """
        This function extracts the title, author, date, URL, tags, and text from an article.
        
        Args:
            article (Dict[str, Any]): a dictionary containing the article's text and metadata.

        Returns:
            Tuple[str]: a tuple containing the title, author, date, URL, tags, and text of the article.
        """
        title = None
        author = None
        date_published = None
        url = None
        tags = None
        text = None
        
        # Get title
        if 'title' in article and 'book_title' in article and article['title']: title = article['title']
        elif 'book_title' in article and 'title' not in article and article['book_title']: 
            title = article['book_title']
            if title[-1] == '\n': title = title[:-1]
        elif 'title' in article and article['title']: 
            title = article['title']
            if title[-1] == '\n': title = title[:-1]
        else: title = None

        # Get author
        if 'author' in article and 'authors' in article and article['author']: author = article['author']
        elif 'authors' in article and article['authors']: author = article['authors']
        elif 'author' in article and article['author']: author = article['author']
        else: author = None

        # Get date published
        if 'date_published' in article and article['date_published'] and len(article['date_published']) >= 10: date_published = article['date_published'][:10]
        elif 'published' in article and article['published'] and len(article['published']) >= 16: date_published = article['published'][:16]
        else: date_published = None
            
        # Get URL
        if 'link' in article and article['link']: url = article['link']
        elif 'url' in article and article['url']: url = article['url']
        elif 'doi' in article and article['doi']: url = article['doi']
        else: url = None
            
        # Get tags
        if 'tags' in article and article['tags']:
            if type(article['tags']) == list: tags = ', '.join([val['term'] for val in article['tags']])
            elif type(article['tags']) == str: tags = article['tags']
            else: tags = None
        
        # Get text
        if 'text' in article and article['text']: text = article['text']
        else:
            raise MissingDataException(f"Entry has no text.")

        return (title, author, date_published, url, tags, text)
           
    def get_alignment_texts(self):
        text_splitter = TokenSplitter(self.min_tokens_per_block, self.max_tokens_per_block)
        with jsonlines.open(self.jsonl_data_path, "r") as reader:
            for entry in reader:
                try:
                    if 'source' not in entry: 
                        if 'url' in entry and entry['url'] == "https://www.cold-takes.com/": 
                            entry["source"] = "Cold Takes"
                        elif 'question' in entry and 'answer' in entry: 
                            entry["source"] = "printouts"
                            continue # for now, skip printouts
                        elif 'article_url' in entry and entry['article_url'] == "https://www.gwern.net":
                            entry["source"] = "gwern.net"
                        elif 'url' in entry and entry['url'] == "https://generative.ink/posts/":
                            entry["source"] = "generative.ink"
                        elif 'url' in entry and entry['url'][:24] == "https://greaterwrong.com":
                            entry["source"] = "greaterwrong.com"
                        else:
                            raise MissingDataException("Entry has no source.")
                    
                    random_number = random.random()
                    if random_number > self.fraction_of_articles_to_use:
                        continue
                    
                    # if we specified custom sources, only include articles from those sources
                    if (self.custom_sources is not None) and (entry['source'] not in self.custom_sources):
                        continue
                    self.articles_count[entry['source']] += 1
                    self.total_articles_count += 1
                    
                    # Get title, author, date, URL, tags, and text
                    title, author, date_published, url, tags, text = self.extract_info_from_article(entry)
                                                            
                    # Get signature
                    signature = ""
                    if title: signature += f"Title: {title}, "
                    if author: signature += f"Author: {author}, "
                    if date_published: signature += f"Date published: {date_published}, "
                    if url: signature += f"URL: {url}, "
                    # if tags: signature += f"Tags: {tags}, "  # Temporary decision to not include tags in the signature
                    if signature: signature = signature[:-2]
                    
                    # Add info to metadata and embedding strings
                    self.metadata.append((title, author, date_published, url, tags, text))
                    blocks = text_splitter.split(text, signature)
                    self.embedding_strings.extend(blocks)
                    
                    # Update counts
                    self.total_char_count += len(text)
                    self.total_word_count += len(text.split())
                    self.total_sentence_count += len(split_into_sentences(text))
                    self.total_block_count += len(blocks)
                
                except MissingDataException as e:
                    if str(e) not in error_count_dict:
                        error_count_dict[str(e)] = 0
                    error_count_dict[str(e)] += 1

    def get_embeddings(self):
        # Get an embedding for each text, with retries if necessary
        @retry(wait=wait_random_exponential(min=1, max=20), stop=stop_after_attempt(5))
        def get_embedding_at_index(text: str, i: int, delay_in_seconds: float = 0) -> np.ndarray:
            time.sleep(delay_in_seconds)
            embedding = openai.Embedding.create(
                model=EMBEDDING_MODEL, 
                input=text
            )
            return i, embedding["data"][0]["embedding"]
        
        start = time.time()
        self.embeddings = np.zeros((len(self.embedding_strings), LEN_EMBEDDINGS))
        
        with concurrent.futures.ThreadPoolExecutor() as executor:
            futures = [executor.submit(get_embedding_at_index, text, i) for i, text in enumerate(self.embedding_strings)]
            num_completed = 0
            for future in concurrent.futures.as_completed(futures):
                i, embedding = future.result()
                self.embeddings[i] = embedding
                num_completed += 1
                if num_completed % 50 == 0:
                    print(f"Completed {num_completed}/{len(self.embedding_strings)} embeddings in {time.time() - start:.2f} seconds.")
        print(f"Completed {num_completed}/{len(self.embedding_strings)} embeddings in {time.time() - start:.2f} seconds.")
    
    def save_embeddings(self, path: str):
        np.save(path, self.embeddings)
        
    def load_embeddings(self, path: str):
        self.embeddings = np.load(path)
        
    def save_class(self, path: str):
        with open(path, 'wb') as f:
            pickle.dump(self, f)
In [131]:
# List of possible sources:
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",
               "Cold Takes", "printouts", "gwern.net", "generative.ink", "greaterwrong.com"] # These sources do not have a source field in the .jsonl file

# List of sources we are using for the test run:
custom_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",
    # "Cold Takes",
    # "printouts",
    # "gwern.net",
    # "generative.ink",
    # "greaterwrong.com"
]

dataset = Dataset(
    jsonl_data_path=PATH_TO_DATA.resolve(), 
    custom_sources=custom_sources, 
    rate_limit_per_minute=3500, 
    min_tokens_per_block=200, max_tokens_per_block=350, 
    # fraction_of_articles_to_use=1/2000
)
dataset.get_alignment_texts()


# with open(PATH_TO_DATASET.resolve(), 'rb') as f:
#     dataset = pickle.load(f)
In [154]:
article_num = 73

example_article_metadata = dataset.metadata[article_num]
print(f"Title: {example_article_metadata[0]}")
print(f"Author: {example_article_metadata[1]}")
print(f"Date published: {example_article_metadata[2]}")
print(f"URL: {example_article_metadata[3]}")
print(f"Tags: {example_article_metadata[4]}")
print(f"Text: {example_article_metadata[5]}")
Title: Model Mis-specification and Inverse Reinforcement Learning
Author: jsteinhardt
Date published: Tue, 07 Feb 2017
URL: https://jsteinhardt.wordpress.com/2017/02/07/model-mis-specification-and-inverse-reinforcement-learning/
Tags: Locomotion
Text: Model Mis-specification and Inverse Reinforcement Learning

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).
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.
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.
Specific Pitfalls for Inverse Reinforcement Learning

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.
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:

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.
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.


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.

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.
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.
Inverse Reinforcement Learning: Definition and Notations

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.)

Figure 1: Diagram showing how IRL and RL are related. (Credit: Pieter Abbeel’s slides on IRL) 
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:

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.).
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:

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).
Recognizing Human Actions in Data

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.
Inferring Reward Functions from Video Frames
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.

Movie still: What actions are being performed in this situation? (Source)
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).
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.
Inferring Policies From Video Frames
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.
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.
IRL Needs Curated Data
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.
Information and Biases

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:
(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.
(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.
(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.
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.
Time-inconsistency and Procrastination
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.

Figure 2. MDP graph for choosing whether to “work” or “wait” (relax) on a task. 
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 .
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.

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 . 
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.)
Long-term Plans

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.
(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).
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.
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?
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.
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.
(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.
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%.
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).
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.
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).
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.
Learning Values != Robustly Predicting Human Behaviour

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.
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.
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.
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.
Further reading

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.
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).
Paul Christiano raised many similar points about mis-specification in a post on his blog.
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”.
Acknowledgments

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.
In [133]:
print(f"Articles count: {len(dataset.metadata)}")
print(f"Num of each source: {dataset.articles_count}")
print(f"Num chars: {dataset.total_char_count}")
print(f"Num words: {dataset.total_word_count}")
print(f"Num sentences: {dataset.total_sentence_count}")
print(f"Num blocks: {dataset.total_block_count}")
Articles count: 140
Num of each source: defaultdict(<class 'int'>, {'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})
Num chars: 2096402
Num words: 335374
Num sentences: 16648
Num blocks: 1818
In [139]:
dataset.get_embeddings()
dataset.save_embeddings(PATH_TO_EMBEDDINGS)
Completed 50/1818 embeddings in 1.75 seconds.
Completed 100/1818 embeddings in 2.48 seconds.
Completed 150/1818 embeddings in 3.32 seconds.
Completed 200/1818 embeddings in 4.09 seconds.
Completed 250/1818 embeddings in 4.94 seconds.
Completed 300/1818 embeddings in 5.83 seconds.
Completed 350/1818 embeddings in 6.62 seconds.
Completed 400/1818 embeddings in 7.43 seconds.
Completed 450/1818 embeddings in 8.23 seconds.
Completed 500/1818 embeddings in 8.90 seconds.
Completed 550/1818 embeddings in 9.60 seconds.
Completed 600/1818 embeddings in 10.39 seconds.
Completed 650/1818 embeddings in 11.25 seconds.
Completed 700/1818 embeddings in 11.92 seconds.
Completed 750/1818 embeddings in 12.73 seconds.
Completed 800/1818 embeddings in 13.69 seconds.
Completed 850/1818 embeddings in 14.88 seconds.
Completed 900/1818 embeddings in 16.02 seconds.
Completed 950/1818 embeddings in 17.34 seconds.
Completed 1000/1818 embeddings in 18.22 seconds.
Completed 1050/1818 embeddings in 19.32 seconds.
Completed 1100/1818 embeddings in 20.44 seconds.
Completed 1150/1818 embeddings in 21.32 seconds.
Completed 1200/1818 embeddings in 22.53 seconds.
Completed 1250/1818 embeddings in 23.46 seconds.
Completed 1300/1818 embeddings in 24.64 seconds.
Completed 1350/1818 embeddings in 25.58 seconds.
Completed 1400/1818 embeddings in 26.62 seconds.
Completed 1450/1818 embeddings in 27.54 seconds.
Completed 1500/1818 embeddings in 28.60 seconds.
Completed 1550/1818 embeddings in 29.78 seconds.
Completed 1600/1818 embeddings in 30.82 seconds.
Completed 1650/1818 embeddings in 31.79 seconds.
Completed 1700/1818 embeddings in 32.79 seconds.
Completed 1750/1818 embeddings in 34.00 seconds.
Completed 1800/1818 embeddings in 35.08 seconds.
Completed 1818/1818 embeddings in 36.30 seconds.
In [140]:
dataset.save_class(PATH_TO_DATASET)
In [141]:
# for embed in dataset.embedding_strings:
#     print(embed)
#     print("\n"*4)
In [142]:
"""
TODO:
Add a moderation call to not be prompt-hacked: https://platform.openai.com/docs/guides/moderation/quickstart
"""

class AlignmentSearch:
    def __init__(self,
            dataset: Dataset,  # Dataset object containing the data.
        ):
        self.metadataset = dataset
    
    @retry(wait=wait_random_exponential(min=1, max=20), stop=stop_after_attempt(4))
    def get_embedding(self, text: str) -> np.ndarray:
        result = openai.Embedding.create(model=EMBEDDING_MODEL, input=text)
        print(f"Embedding created for query: {text}")
        return result["data"][0]["embedding"]
        # except openai.RateLimitError as e:
        #     print("Rate limit exceeded. Retrying in 30 seconds.")
        #     time.sleep(30)
        #     raise e
    
    def get_top_k(self, query: str, k: int=10) -> List[str]:
        # Receives a query (str) and returns the top k blocks that are most semantically similar to the query.
        # Each tuple contains the title of an article, its URL, and text.
        query_embedding = self.get_embedding(query)
        similarities = np.dot(self.metadataset.embeddings, query_embedding)
        top_k_indices = np.argsort(similarities)[::-1][:k]
        top_k = [self.metadataset.embedding_strings[i] for i in top_k_indices]
        return top_k
    
    def limit_tokens(self, text: str, max_tokens: int, encoding_name: str = "cl100k_base") -> str:
        encoding = tiktoken.get_encoding(encoding_name)
        tokens = encoding.encode(text)[:max_tokens]
        return encoding.decode(tokens)
    
    def construct_messages(self, question: str, blocks: List[str] = None, mode: str = "balanced") -> str:
        # Receives a question (str) and a list of blocks and returns a prompt (str) to be used for text generation.
        context = ""
        if blocks:
            for i, block in enumerate(blocks):
                context += f'Context #{i+1}: """{block}"""\n\n'
            context = self.limit_tokens(context, 2000)

        if mode == "creative":
            raise NotImplementedError

        elif mode == "balanced":
            system = '''You are a helpful assistant.'''
            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.'''
            
            messages = [
                {"role": "system", "content": system},
                {"role": "user", "content": f"{user_prompt}\n\n{context}\n\nQuestion: {question}"}
            ]
        
        elif mode == "precise":
            raise NotImplementedError

        elif mode == "HyDE":
            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."
            messages = [
                {"role": "system", "content": assistant_prompt},
                {"role": "user", "content": question},
            ]
            
        else:
            raise ValueError("Mode must be one of 'balanced', 'precise', 'creative', or 'HyDE'.")
        
        return messages
    
    def answer_question(self, question: str, blocks: List[str]) -> str:
        # Receives a question (str) and a list of blocks and returns an answer (str) to the question.
        messages = self.construct_messages(question, blocks, mode="balanced")
        answer = openai.ChatCompletion.create(
            model=COMPLETIONS_MODEL, 
            messages=messages
        )
        return answer["choices"][0]["message"]["content"]
    
    def search_and_answer(self, question: str, k: int=10, HyDE: bool=False) -> str:
        # Receives a question (str) and returns an answer (str) to the question.
        if HyDE:
            messages = self.construct_messages(question, mode="HyDE")
            hyde_completion = openai.ChatCompletion.create(
                model=COMPLETIONS_MODEL, 
                messages=messages
            )
            top_k = self.get_top_k(f"{question}\n{hyde_completion}", k)
        else:
            top_k = self.get_top_k(question, k)
        answer = self.answer_question(question, top_k)
        return answer, top_k# , sources
In [156]:
k = 6
AS = AlignmentSearch(dataset=dataset)
query = """Say I don't know."""
# top_k_sources = AS.get_top_k(query, k)
answer, top_k_sources = AS.search_and_answer(query, k)#, HyDE=True)
print(answer)
Embedding created for query: Recognizing Human Actions in Data
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.
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
Cell In[156], line 6
      3 query = """Recognizing Human Actions in Data
      4 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."""
      5 # top_k_sources = AS.get_top_k(query, k)
----> 6 answer, top_k_sources = AS.search_and_answer(query, k)#, HyDE=True)
      7 print(answer)

Cell In[142], line 93, in AlignmentSearch.search_and_answer(self, question, k, HyDE)
     91 else:
     92     top_k = self.get_top_k(question, k)
---> 93 answer = self.answer_question(question, top_k)
     94 return answer, top_k

Cell In[142], line 76, in AlignmentSearch.answer_question(self, question, blocks)
     73 def answer_question(self, question: str, blocks: List[str]) -> str:
     74     # Receives a question (str) and a list of blocks and returns an answer (str) to the question.
     75     messages = self.construct_messages(question, blocks, mode="balanced")
---> 76     answer = openai.ChatCompletion.create(
     77         model=COMPLETIONS_MODEL, 
     78         messages=messages
     79     )
     80     return answer["choices"][0]["message"]["content"]

File ~\AppData\Roaming\Python\Python310\site-packages\openai\api_resources\chat_completion.py:25, in ChatCompletion.create(cls, *args, **kwargs)
     23 while True:
     24     try:
---> 25         return super().create(*args, **kwargs)
     26     except TryAgain as e:
     27         if timeout is not None and time.time() > start + timeout:

File ~\AppData\Roaming\Python\Python310\site-packages\openai\api_resources\abstract\engine_api_resource.py:153, in EngineAPIResource.create(cls, api_key, api_base, api_type, request_id, api_version, organization, **params)
    127 @classmethod
    128 def create(
    129     cls,
   (...)
    136     **params,
    137 ):
    138     (
    139         deployment_id,
    140         engine,
   (...)
    150         api_key, api_base, api_type, api_version, organization, **params
    151     )
--> 153     response, _, api_key = requestor.request(
    154         "post",
    155         url,
    156         params=params,
    157         headers=headers,
    158         stream=stream,
    159         request_id=request_id,
    160         request_timeout=request_timeout,
    161     )
    163     if stream:
    164         # must be an iterator
    165         assert not isinstance(response, OpenAIResponse)

File ~\AppData\Roaming\Python\Python310\site-packages\openai\api_requestor.py:216, in APIRequestor.request(self, method, url, params, headers, files, stream, request_id, request_timeout)
    205 def request(
    206     self,
    207     method,
   (...)
    214     request_timeout: Optional[Union[float, Tuple[float, float]]] = None,
    215 ) -> Tuple[Union[OpenAIResponse, Iterator[OpenAIResponse]], bool, str]:
--> 216     result = self.request_raw(
    217         method.lower(),
    218         url,
    219         params=params,
    220         supplied_headers=headers,
    221         files=files,
    222         stream=stream,
    223         request_id=request_id,
    224         request_timeout=request_timeout,
    225     )
    226     resp, got_stream = self._interpret_response(result, stream)
    227     return resp, got_stream, self.api_key

File ~\AppData\Roaming\Python\Python310\site-packages\openai\api_requestor.py:516, in APIRequestor.request_raw(self, method, url, params, supplied_headers, files, stream, request_id, request_timeout)
    514     _thread_context.session = _make_session()
    515 try:
--> 516     result = _thread_context.session.request(
    517         method,
    518         abs_url,
    519         headers=headers,
    520         data=data,
    521         files=files,
    522         stream=stream,
    523         timeout=request_timeout if request_timeout else TIMEOUT_SECS,
    524     )
    525 except requests.exceptions.Timeout as e:
    526     raise error.Timeout("Request timed out: {}".format(e)) from e

File c:\Python310\lib\site-packages\requests\sessions.py:587, in Session.request(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)
    582 send_kwargs = {
    583     "timeout": timeout,
    584     "allow_redirects": allow_redirects,
    585 }
    586 send_kwargs.update(settings)
--> 587 resp = self.send(prep, **send_kwargs)
    589 return resp

File c:\Python310\lib\site-packages\requests\sessions.py:701, in Session.send(self, request, **kwargs)
    698 start = preferred_clock()
    700 # Send the request
--> 701 r = adapter.send(request, **kwargs)
    703 # Total elapsed time of the request (approximately)
    704 elapsed = preferred_clock() - start

File c:\Python310\lib\site-packages\requests\adapters.py:489, in HTTPAdapter.send(self, request, stream, timeout, verify, cert, proxies)
    487 try:
    488     if not chunked:
--> 489         resp = conn.urlopen(
    490             method=request.method,
    491             url=url,
    492             body=request.body,
    493             headers=request.headers,
    494             redirect=False,
    495             assert_same_host=False,
    496             preload_content=False,
    497             decode_content=False,
    498             retries=self.max_retries,
    499             timeout=timeout,
    500         )
    502     # Send the request.
    503     else:
    504         if hasattr(conn, "proxy_pool"):

File c:\Python310\lib\site-packages\urllib3\connectionpool.py:703, in HTTPConnectionPool.urlopen(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw)
    700     self._prepare_proxy(conn)
    702 # Make the request on the httplib connection object.
--> 703 httplib_response = self._make_request(
    704     conn,
    705     method,
    706     url,
    707     timeout=timeout_obj,
    708     body=body,
    709     headers=headers,
    710     chunked=chunked,
    711 )
    713 # If we're going to release the connection in ``finally:``, then
    714 # the response doesn't need to know about the connection. Otherwise
    715 # it will also try to release it and we'll have a double-release
    716 # mess.
    717 response_conn = conn if not release_conn else None

File c:\Python310\lib\site-packages\urllib3\connectionpool.py:449, in HTTPConnectionPool._make_request(self, conn, method, url, timeout, chunked, **httplib_request_kw)
    444             httplib_response = conn.getresponse()
    445         except BaseException as e:
    446             # Remove the TypeError from the exception chain in
    447             # Python 3 (including for exceptions like SystemExit).
    448             # Otherwise it looks like a bug in the code.
--> 449             six.raise_from(e, None)
    450 except (SocketTimeout, BaseSSLError, SocketError) as e:
    451     self._raise_timeout(err=e, url=url, timeout_value=read_timeout)

File <string>:3, in raise_from(value, from_value)

File c:\Python310\lib\site-packages\urllib3\connectionpool.py:444, in HTTPConnectionPool._make_request(self, conn, method, url, timeout, chunked, **httplib_request_kw)
    441 except TypeError:
    442     # Python 3
    443     try:
--> 444         httplib_response = conn.getresponse()
    445     except BaseException as e:
    446         # Remove the TypeError from the exception chain in
    447         # Python 3 (including for exceptions like SystemExit).
    448         # Otherwise it looks like a bug in the code.
    449         six.raise_from(e, None)

File c:\Python310\lib\http\client.py:1374, in HTTPConnection.getresponse(self)
   1372 try:
   1373     try:
-> 1374         response.begin()
   1375     except ConnectionError:
   1376         self.close()

File c:\Python310\lib\http\client.py:318, in HTTPResponse.begin(self)
    316 # read until we get a non-100 response
    317 while True:
--> 318     version, status, reason = self._read_status()
    319     if status != CONTINUE:
    320         break

File c:\Python310\lib\http\client.py:279, in HTTPResponse._read_status(self)
    278 def _read_status(self):
--> 279     line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
    280     if len(line) > _MAXLINE:
    281         raise LineTooLong("status line")

File c:\Python310\lib\socket.py:705, in SocketIO.readinto(self, b)
    703 while True:
    704     try:
--> 705         return self._sock.recv_into(b)
    706     except timeout:
    707         self._timeout_occurred = True

File c:\Python310\lib\ssl.py:1274, in SSLSocket.recv_into(self, buffer, nbytes, flags)
   1270     if flags != 0:
   1271         raise ValueError(
   1272           "non-zero flags not allowed in calls to recv_into() on %s" %
   1273           self.__class__)
-> 1274     return self.read(nbytes, buffer)
   1275 else:
   1276     return super().recv_into(buffer, nbytes, flags)

File c:\Python310\lib\ssl.py:1130, in SSLSocket.read(self, len, buffer)
   1128 try:
   1129     if buffer is not None:
-> 1130         return self._sslobj.read(len, buffer)
   1131     else:
   1132         return self._sslobj.read(len)

KeyboardInterrupt: 
In [153]:
for source in top_k_sources:
    print(source)
    print("\n"*4)
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.
 - 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/





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.
 - 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/





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.
 - 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/





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.
 - 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/





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.
 - 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/





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.
 - 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/





In [ ]:
answer
('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.',
 [' 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',
  " 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",
  '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',
  ' 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',
  "/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",
  '/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',
  " 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",
  " 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",
  " 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",
  ' 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'])

Tests

Comparing quantity of articles/words/tokens/characters in the official dataset vs. what we have

In [158]:
num_articles_truth = {
    'https://aipulse.org': 23,
    'ebook': 23,
    'https://qualiacomputing.com': 278,
    'alignment forum': 2138,
    'lesswrong': 28252 + 227,
    'manual': "?",
    'arxiv': 707 + 1679 + 1000 + 4621,
    'https://deepmindsafetyresearch.medium.com/': 10,
    'waitbutwhy.com': 2,
    'GitHub': "?",
    'https://aiimpacts.org': 227,
    'arbital.com': 223,
    'carado.moe': 59,
    'nonarxiv_papers': "?",
    'https://vkrakovna.wordpress.com': 43,
    'https://jsteinhardt.wordpress.com': 39,
    'audio-transcripts': 25 + 12,
    'https://intelligence.org': 479,
    'youtube': 457,
    'reports': "?",
    'https://aisafety.camp': 8,
    'curriculum': "?",
    'https://www.yudkowsky.net': 23,
    'distill': 49,
    '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    
}
word_count_truth = 53_550_146
char_count_truth = 351_767_163

# Print table. First row has Truth and Empirical findings.
print(f"{'Source':<20} {'Truth':<10} {'Empirical':<10} {'Difference':<10}")
for source in dataset.articles_count:
    try:
        print(f"{source[:20]:<20} {num_articles_truth[source]:<10} {dataset.articles_count[source]:<10} {num_articles_truth[source] - dataset.articles_count[source]:<10}")
    except TypeError:
        print(f"{source[:20]:<20} {num_articles_truth[source]:<10} {dataset.articles_count[source]:<10} {'UNKNOWN':<10}")

# Compare true and empirical word counts and character counts
print(f"\n{'':<20} {'Truth':<10} {'Empirical':<10} {'Difference':<10}")
print(f"{'Word Count':<20} {word_count_truth:<10} {dataset.total_word_count:<10} {word_count_truth - dataset.total_word_count:<10}")
print(f"{'Character Count':<20} {char_count_truth:<10} {dataset.total_char_count:<10} {char_count_truth - dataset.total_char_count:<10}")
Source               Truth      Empirical  Difference
https://aipulse.org  23         23         0         
manual               ?          1          UNKNOWN   
waitbutwhy.com       2          2          0         
https://vkrakovna.wo 43         43         0         
https://jsteinhardt. 39         39         0         
https://aisafety.cam 8          8          0         
curriculum           ?          1          UNKNOWN   
https://www.yudkowsk 23         23         0         

                     Truth      Empirical  Difference
Word Count           53550146   335374     53214772  
Character Count      351767163  2096402    349670761 

Embeeding time estimation

In [ ]:
# Define a helper function that takes in a single string and outputs a single d-dimensional vector
def get_embedding(text):
  # Use the embeddings OpenAI API endpoint to get an embedding for the text
  result = openai.Embedding.create(model=EMBEDDING_MODEL, input=text)
  # Convert the response to a numpy array and return it
  return result["data"][0]["embedding"]

# Define a function that takes in a list of strings and outputs a numpy matrix of embeddings
def get_embeddings(texts):
  embeddings = []
  with concurrent.futures.ThreadPoolExecutor() as executor:
    futures = [executor.submit(get_embedding, text) for text in texts]
    for future in concurrent.futures.as_completed(futures):
      embeddings.append(future.result())
  return np.vstack(embeddings)

def get_embeddings_not_parallel(texts):
    embeddings = np.array([get_embedding(text) for text in texts])
    return embeddings
In [ ]:
# Define a list of texts to be embedded
texts = ["Hello world!"] * 100

# Regular method
start = time.time()
embeddings_1 = get_embeddings_not_parallel(texts)
end = time.time()
print(f"Regular method: {end - start}s")

# Parallel method
start = time.time()
embeddings_2 = get_embeddings(texts)
end = time.time()
print(f"Parallel method: {end - start}s")
Regular method: 23.137897491455078
Parallel method: 1.7662100791931152
(100, 1536)
(100, 1536)

Conclusion: async method is ~10x faster than sync method

Streaming ChatGPT response

In [ ]:
import asyncio
import config
import openai
openai.api_key = config.OPENAI_API_KEY
In [2]:
import asyncio

async def test_stream(question: str):
  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."
  
  messages = [
    {"role": "system", "content": assistant_prompt},
    {"role": "user", "content": question},
  ]
  async for part in await openai.ChatCompletion.acreate(
    model=COMPLETIONS_MODEL,
    messages=messages,
    stream=True
  ):
    finish_reason = part["choices"][0]["finish_reason"]
    if "content" in part["choices"][0]["delta"]:
      content = part["choices"][0]["delta"]["content"]
      print(content, end="")
    elif finish_reason:
      print(finish_reason)

if __name__ == '__main__':
  question = "What is the Natural Abstraction Hypothesis?"
  asyncio.run(test_stream(question))
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
Cell In[2], line 24
     22 if __name__ == '__main__':
     23   question = "What is the Natural Abstraction Hypothesis?"
---> 24   asyncio.run(test_stream(question))

File c:\Python310\lib\asyncio\runners.py:33, in run(main, debug)
      9 """Execute the coroutine and return the result.
     10 
     11 This function runs the passed coroutine, taking care of
   (...)
     30     asyncio.run(main())
     31 """
     32 if events._get_running_loop() is not None:
---> 33     raise RuntimeError(
     34         "asyncio.run() cannot be called from a running event loop")
     36 if not coroutines.iscoroutine(main):
     37     raise ValueError("a coroutine was expected, got {!r}".format(main))

RuntimeError: asyncio.run() cannot be called from a running event loop
In [ ]:
import tiktoken
encoding = tiktoken.get_encoding("cl100k_base")
encoding.encode("tiktoken is great!")

def num_tokens_from_string(string: str, encoding_name: str) -> int:
    """Returns the number of tokens in a text string."""
    encoding = tiktoken.get_encoding(encoding_name)
    num_tokens = len(encoding.encode(string))
    return num_tokens

a = num_tokens_from_string("tiktoken is great!", "cl100k_base")
print(a)
# Output: 6

def num_tokens_from_messages(messages, model="gpt-3.5-turbo-0301"):
    """Returns the number of tokens used by a list of messages."""
    try:
        encoding = tiktoken.encoding_for_model(model)
    except KeyError:
        encoding = tiktoken.get_encoding("cl100k_base")
    except AttributeError:
        encoding = tiktoken.get_encoding("cl100k_base")
    if model == "gpt-3.5-turbo-0301":  # note: future models may deviate from this
        num_tokens = 0
        for message in messages:
            num_tokens += 4  # every message follows <im_start>{role/name}\n{content}<im_end>\n
            for key, value in message.items():
                num_tokens += len(encoding.encode(value))
                if key == "name":  # if there's a name, the role is omitted
                    num_tokens += -1  # role is always required and always 1 token
        num_tokens += 2  # every reply is primed with <im_start>assistant
        return num_tokens
    else:
        raise NotImplementedError(f"""num_tokens_from_messages() is not presently implemented for model {model}.
See https://github.com/openai/openai-python/blob/main/chatml.md for information on how messages are converted to tokens.""")
b = num_tokens_from_messages([{"name": "user", "content": "hello"}], model="gpt-3.5-turbo-0301")
print(b)
# Output: 7
In [ ]:
import tiktoken

def limit_tokens(text: str, max_tokens: int, encoding_name: str = "cl100k_base") -> str:
    encoding = tiktoken.get_encoding(encoding_name)
    tokens = encoding.encode(text)[:max_tokens]
    return encoding.decode(tokens)

# Example usage
input_text = "tiktoken is a great library to work with tokens in text!"
limited_text = limit_tokens(input_text, 1000)
print(limited_text)
tiktoken is a great library to work with tokens in text!
In [5]:
import pinecone
import config
PINECONE_API_KEY = config.PINECONE_API_KEY

pinecone.init(api_key=PINECONE_API_KEY, environment="us-central1-gcp")
In [6]:

pinecone.create_index("quickstart", dimension=8, metric="euclidean", pod_type="p1")
pinecone.list_indexes()
# Returns:
# ['quickstart']
Out [6]:
['quickstart']
In [7]:
index = pinecone.Index("quickstart")
In [8]:
# Upsert sample data (5 8-dimensional vectors)
index.upsert([
    ("A", [0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1]),
    ("B", [0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2]),
    ("C", [0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3]),
    ("D", [0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4]),
    ("E", [0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5])
])
Out [8]:
{'upserted_count': 5}
In [9]:
index.describe_index_stats()
# Returns:
# {'dimension': 8, 'index_fullness': 0.0, 'namespaces': {'': {'vector_count': 5}}}
Out [9]:
{'dimension': 8,
 'index_fullness': 0.0,
 'namespaces': {'': {'vector_count': 5}},
 'total_vector_count': 5}
In [10]:
index.query(
  vector=[0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3],
  top_k=3,
  include_values=True
)
# Returns:
# {'matches': [{'id': 'C',
#               'score': 0.0,
#               'values': [0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3]},
#              {'id': 'D',
#               'score': 0.0799999237,
#               'values': [0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4]},
#              {'id': 'B',
#               'score': 0.0800000429,
#               'values': [0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2]}],
#  'namespace': ''}
Out [10]:
{'matches': [{'id': 'C',
              'score': 0.0,
              'values': [0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3, 0.3]},
             {'id': 'D',
              'score': 0.0799999237,
              'values': [0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4]},
             {'id': 'B',
              'score': 0.0800000429,
              'values': [0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2]}],
 'namespace': ''}
In [ ]:
pinecone.delete_index("quickstart")