• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Aucun tag

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Emergent generative agents


Commit MetaInfo

Révision356751b59d378fbe6ea336211e0c3588cd08eccb (tree)
l'heure2023-06-12 03:14:32
AuteurCorbin <cds@corb...>
CommiterCorbin

Message de Log

Add WP query access, and fix a few bugs.

Most importantly, make choices on RWKV work. The same technique should
work on LLaMA too.

Change Summary

Modification

--- a/flake.nix
+++ b/flake.nix
@@ -52,9 +52,22 @@
5252
5353 doCheck = false;
5454 };
55+ mediawiki = pkgs.python310.pkgs.buildPythonPackage rec {
56+ pname = "pymediawiki";
57+ version = "0.7.2";
58+
59+ src = pkgs.fetchPypi {
60+ inherit pname version;
61+ sha256 = "sha256-4KjtKSnWBRyZgHrnUCwdKwSx9FftkQ2+vJuptfnWqUI=";
62+ };
63+
64+ propagatedBuildInputs = with pkgs.python310.pkgs; [
65+ beautifulsoup4 requests
66+ ];
67+ };
5568 py = pkgs.python310.withPackages (ps: with ps; [
5669 faiss llama-cpp-python sentence-transformers tokenizers transformers torch
57- twisted
70+ twisted mediawiki
5871 ]);
5972 rwkv = pkgs.stdenv.mkDerivation {
6073 name = "rwkv.cpp";
--- a/src/agent.py
+++ b/src/agent.py
@@ -4,6 +4,7 @@ from collections import deque
44 from datetime import datetime
55 import json
66 import os.path
7+import random
78 import re
89 from string import ascii_uppercase
910 import sys
@@ -16,6 +17,9 @@ from twisted.internet.task import LoopingCall, deferLater
1617 from twisted.internet.threads import deferToThread
1718 from twisted.words.protocols.irc import IRCClient
1819
20+from mediawiki import MediaWiki
21+from mediawiki.exceptions import DisambiguationError, MediaWikiException, PageError
22+
1923 from common import irc_line, Timer, SentenceIndex, breakAt
2024 from gens.camelid import CamelidGen
2125 from gens.mawrkov import MawrkovGen
@@ -54,6 +58,7 @@ prologues = {
5458 "thoughts": "Then I thought to myself:",
5559 "choice": "Then I chose what to do next:",
5660 "irc": "Then I chatted on IRC, channel {subtag}:",
61+ "wp": "Then I searched Wikipedia by title and read a summary:",
5762 }
5863
5964 class Mind:
@@ -155,6 +160,7 @@ uppercase = ascii_uppercase[1:]
155160 choices = {
156161 "irc": "Chat on IRC, channel {subtag}",
157162 "thoughts": "Think to myself for a moment",
163+ "wp": "Search Wikipedia",
158164 }
159165 def choicify(options):
160166 return " ".join(f"({c}) {o}" for c, o in zip(uppercase, options))
@@ -166,7 +172,10 @@ class ChoiceMaker(Agent):
166172 self.mind = mind
167173 self.possibilities = set()
168174 self.actions = {}
169- def overhear(self, tag, subtag, s): self.possibilities.add((tag, subtag))
175+ def overhear(self, tag, subtag, s):
176+ # XXX hack
177+ if tag == "irc" and subtag is None: return
178+ self.possibilities.add((tag, subtag))
170179 def dispatch(self, tag, subtag):
171180 if tag in self.actions: return self.actions[tag](subtag)
172181 def idle(self):
@@ -176,11 +185,19 @@ class ChoiceMaker(Agent):
176185 if len(possibilities) == 0: return
177186 elif len(possibilities) == 1: return self.dispatch(*possibilities[0])
178187
188+ random.shuffle(possibilities)
179189 prompt = choicify([choices[tag].format(subtag=subtag)
180190 for tag, subtag in possibilities])
181191 d = self.mind.forceChoice(self.tag, self.subtag, prompt + " My choice: ",
182192 uppercase[:len(possibilities)])
183- d.addCallback(lambda s: self.dispatch(*possibilities[indexify(s)]))
193+
194+ @d.addCallback
195+ def cb(s):
196+ index = indexify(s)
197+ try: return self.dispatch(*possibilities[index])
198+ except IndexError:
199+ self.broadcast("But that was an invalid choice, so I had to choose again.")
200+ return deferLater(reactor, 0.0, self.idle)
184201 return d
185202
186203 class ChainOfThoughts(Agent):
@@ -198,7 +215,7 @@ class Recall(Agent):
198215 tag = "memories"
199216 def __init__(self, index, seed, idle):
200217 self.index = index
201- self.recentThoughts = deque([seed], maxlen=5)
218+ self.recentThoughts = deque([seed], maxlen=25)
202219 self.idle = idle
203220
204221 def go(self):
@@ -216,11 +233,11 @@ class Recall(Agent):
216233 if thought not in self.recentThoughts:
217234 new += 1
218235 self.recentThoughts.append(thought)
219- self.broadcast(thought)
236+ deferLater(reactor, 0.0, self.broadcast, thought)
220237 return new
221238
222239
223-IRC_LINE_HEAD = re.compile(r"\d{1,2}:\d{1,2}:\d{1,2} <")
240+IRC_LINE_HEAD = re.compile(r"\d{1,2}:\d{1,2}:\d{1,2}( #[-a-z]+)? <")
224241 def breakIRCLine(line):
225242 return IRC_LINE_HEAD.split(breakAt(line.strip(), "\n"), maxsplit=1)[0]
226243
@@ -244,8 +261,7 @@ class IRCAgent(Agent, IRCClient):
244261 def userLeft(self, user, channel):
245262 self.broadcastTagged(channel, f"{user} leaves {channel}")
246263
247- def userQuit(self, user, channel):
248- self.broadcastTagged(channel, f"{user} quits {channel}")
264+ def userQuit(self, user, reason): self.broadcast(f"{user} quit")
249265
250266 def topicUpdated(self, user, channel, topic):
251267 self.broadcastTagged(channel, f"Topic for {channel} is now: {topic}")
@@ -281,6 +297,36 @@ class IRCFactory(ClientFactory):
281297 self.cm.actions["irc"] = protocol.speakInChannel
282298 return protocol
283299
300+class ReadWP(Agent):
301+ tag = "wp"
302+ def __init__(self, mind):
303+ self.wp = MediaWiki()
304+ self.mind = mind
305+
306+ def go(self):
307+ d = self.mind.infer(self.tag, self.subtag, "Title search:")
308+
309+ @d.addCallback
310+ def cb(title):
311+ title = title.strip()
312+ if not title:
313+ self.broadcast("No query provided; trying again.")
314+ return deferLater(reactor, 0.0, self.go)
315+ try:
316+ page = self.wp.page(title)
317+ summary = page.summary[:200]
318+ if len(page.summary) > 200: summary += "..."
319+ self.broadcast("Title: " + page.title)
320+ self.broadcast("Summary: " + summary)
321+ except DisambiguationError as de:
322+ self.broadcast("Ambiguous query. Possible titles: " +
323+ ", ".join(de.options))
324+ except MediaWikiException:
325+ self.broadcast("Search query was too long.")
326+ except PageError: self.broadcast("No article with that title.")
327+
328+ return d
329+
284330 def go():
285331 print("~ Starting tasks…")
286332 clock = Clock()
@@ -305,11 +351,16 @@ def go():
305351
306352 memories = Recall(thoughtIndex, firstStatement, cm.idle)
307353 memories.listeners = lbi, mind
308- LoopingCall(memories.go).start(60 * 2, now=True)
354+ LoopingCall(memories.go).start(60 * 5, now=True)
309355
310356 thoughts = ChainOfThoughts(mind, cm.idle)
311357 thoughts.listeners = memories, lbi, mind
312- LoopingCall(thoughts.go).start(60 * 2, now=False)
358+ LoopingCall(thoughts.go).start(60 * 5, now=False)
359+
360+ readwp = ReadWP(mind)
361+ readwp.listeners = cm, lbi, mind
362+ LoopingCall(readwp.go).start(60 * 30, now=True)
363+ cm.actions["wp"] = lambda subtag: readwp.go()
313364
314365 factory = IRCFactory(mind, cm, (memories, lbi, cm, mind),
315366 title,
--- a/src/gens/mawrkov.py
+++ b/src/gens/mawrkov.py
@@ -70,7 +70,4 @@ class MawrkovYarn(Yarn):
7070 self.feedForward([token])
7171 return tokens
7272
73- def force(self, options):
74- # +10 is hopefully not too much.
75- biases = {opt: 10 for opt in options}
76- return sampling.sample_logits(self.logits, TEMPERATURE, TOP_P, biases)
73+ def force(self, options): return max(options, key=self.logits.__getitem__)