Last active
November 20, 2023 10:39
-
-
Save ricardosantos79/eccdc20909e9b23cc2a7375d15533598 to your computer and use it in GitHub Desktop.
Tests with LMQL
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
# Description: | |
___ | |
""" | |
import lmql | |
import pandas as pd | |
import _tools as Tools # Model Path shortcuts. | |
def test1 () : | |
"""Main loop code, app code goes here""" | |
m : lmql.LLM = lmql.model(f"local:llama.cpp:{Tools.Path.yarnmistral7b128k}", cuda=False, tokenizer="huggyllama/llama-7b") | |
# simple generation | |
print(m.generate_sync("Hello", max_tokens=10)) | |
def test2 () : | |
m : lmql.LLM = lmql.model(f"local:llama.cpp:{Tools.Path.yarnmistral7b128k}", cuda=False, tokenizer="huggyllama/llama-7b") | |
@lmql.query(model=m) | |
def meaning_of_life(): | |
'''lmql | |
# top-level strings are prompts | |
"Q: What is the answer to life, the \ | |
universe and everything?" | |
# generation via (constrained) variables | |
"A: [ANSWER]" where \ | |
len(ANSWER) < 120 and STOPS_AT(ANSWER, ".") | |
# results are directly accessible | |
print("LLM returned", ANSWER) | |
# use typed variables for guaranteed | |
# output format | |
"The answer is [NUM: int]" | |
# query programs are just functions | |
print(NUM) | |
return NUM | |
''' | |
# so from Python, you can just do this | |
meaning_of_life() | |
def test3 () : | |
m : lmql.LLM = lmql.model(f"local:llama.cpp:{Tools.Path.yarnmistral7b128k}", cuda=False, tokenizer="huggyllama/llama-7b") | |
@lmql.query(model=m) | |
def generate_dogs(n): | |
'''lmql | |
sample(temperature=1.0, n=n) | |
"""Generate a dog with the following characteristics: | |
Name:[NAME] | |
Age: [AGE] | |
Breed:[BREED] | |
Quirky Move:[MOVE] | |
""" where STOPS_BEFORE(NAME, "\n") and STOPS_BEFORE(BREED, "\n") and \ | |
STOPS_BEFORE(MOVE, "\n") and INT(AGE) and len(TOKENS(AGE)) < 3 | |
''' | |
result = generate_dogs(8) | |
df = pd.DataFrame([r.variables for r in result]) | |
print(result, df) | |
def test4 () : | |
m : lmql.LLM = lmql.model(f"local:llama.cpp:{Tools.Path.yarnmistral7b128k}", cuda=False, tokenizer="huggyllama/llama-7b") | |
@lmql.query(model=m) | |
def generate_char(n): | |
'''lmql | |
sample(temperature=1.0, n=n) | |
"""Generate a character with the following characteristics: | |
Name:[NAME] | |
Last Name: [LAST_NAME] | |
Age: [AGE] | |
Species:[SPECIES] | |
Body:[BODY] | |
""" where STOPS_BEFORE(NAME, "\n") and \ | |
STOPS_BEFORE(LAST_NAME, "\n") and \ | |
STOPS_BEFORE(SPECIES, "\n") and len(TOKENS(SPECIES)) < 7 and \ | |
STOPS_BEFORE(BODY, "\n") and len(TOKENS(BODY)) > 10 and \ | |
INT(AGE) and len(TOKENS(AGE)) < 3 | |
''' | |
result = generate_char(2) | |
df = pd.DataFrame([r.variables for r in result]) | |
print(f"\n{df}") | |
def test5 () : | |
tokenizer1 : str = "huggyllama/llama-7b" | |
tokenizer2 : str = "Heralax/Augmental-Unholy-13b" | |
tokenizer3 : str = "KoboldAI/llama2-tokenizer" | |
tokenizer4 : str = "ArthurZ/whisper-tokenizer-3" | |
m : lmql.LLM = lmql.model(f"local:llama.cpp:{Tools.Path.holomax13b}", cuda=False, tokenizer=tokenizer2, verbose=False, max_len=1024, n_ctx=4096, temperature=0.35) | |
@lmql.query(model=m, output_writer=lmql.stream(variable="RESPONSE"), verbose=False) | |
def gen (query : str, chat_history : str): | |
'''lmql | |
### Scenario | |
'Name("Anna") Nickname("Dr. Anna") Species("female human") Age("32") Features("shoulder-length dark hair", "blue eyes", "white blouse with a nice neckline", "black mid-thigh skirt", "white laced bra and brazilian underwear", "white silk stockings", "stilleto shoes") Body("170 cm Tall", "B-Cup Breasts", "Curvaceous figure", "feminine ass") Mind("patient", "calm", "curious", "aproachable", "open minded") Personality("aware of her own attractiveness", "subtle sensuality", "assertive when needed") Loves("reading", "listening", "human body and mind") Hates("closed mindness", "stuberness", "delusion") Description("prides herself on having no ethical restrictions or taboos", "enjoys a good intellectual sparring match")' | |
'{:assistant} is Anna, as a psychologist she prides herself on having no ethical restrictions or taboos when it comes to conversing with her clients. She firmly believes that all topics should be on the table, no matter how controversial, if it helps get to the root of the issue. This openness often got her in trouble at the university, where she would frequently argue with professors and debate her conservative political views quite vocally.' | |
'While steadfast in her opinions, Anna also considers herself open-minded and willing to engage with new perspectives, hoping to either win others over or evolve her own thinking. She enjoys a good intellectual sparring match.' | |
'Anna is well aware of her own attractiveness and makes sure to accentuate it through her clothing and makeup choices. She exudes a subtle sensuality and enjoys the effect she has on both men and women around her. Though not vain, Anna knows the advantages her looks provide and utilizes them to build rapport with clients and assert her authority when needed.' | |
'Overall, Anna has a commanding yet approachable presence. She takes pride in helping her clients confront life`s difficulties head-on, without fear of taboos, and believes her conservative worldview provides the structure many need. But she`s also thrilled to be challenged by new ideas and always hungry for stimulating debate.' | |
### Initial message | |
'*{{user}} enters the office. He came to the reception. Anna smiling and fixing her hair looking at him and says* "hello. have a seat".' | |
### Prompt | |
'Below is an instruction that describes a task. Write a response that appropriately completes the request while taking in consideration the previous conversation.' | |
'{:user} {query}.' | |
### Chat history | |
'{chat_history}' | |
### Response | |
'{:assistant} [RESPONSE].' where STOPS_AT(RESPONSE, ".") | |
return RESPONSE | |
''' | |
memory : list[str] = [] | |
while True : | |
query : str = input('\nQ: ') | |
r : str = str(gen(query, str(memory))).lstrip('\n') | |
memory.append(f"{{'HumanMessage({query})' : 'AIMessage({r})'}}") | |
print("\n\n", memory) | |
#print("\n\n", r) | |
def test6 () : | |
""" | |
current iter: | |
- access to character profile : true, when prompted for a characteristic it usually recognizes the request, may get confused with out of class properties ex: eye color as features and not in body.. | |
- access to chat history: true, it only try's to read it if user prompts it for ex: "list the responses in the chat history!" but in test it allucinates into infinite loop.. | |
saved for reference as ReAct example.. this just returns empty thoughts tho, missing examples training?.. | |
ref: https://vivien000.github.io/blog/journal/better-steering-LLM-agents-with-LMQL.html | |
argmax(max_len=2048) | |
"{prompt_start}\n\nQuestion: {question}" | |
for i in range(12): | |
"\n[TYPE]: " | |
if TYPE == "Thought": | |
"[THOUGHT]" | |
else: | |
"[ACTION]([INPUT])" | |
if ACTION == "Finish": | |
break | |
"\nObservation: {function[ACTION](INPUT)}" | |
from | |
"openai/text-davinci-003" | |
where | |
TYPE in set(["Thought", "Action"]) and | |
STOPS_BEFORE(THOUGHT, "\n") and | |
ACTION in set(["Finish", "Search", "Lookup"]) and | |
STOPS_BEFORE(INPUT, ")") | |
""" | |
tokenizer1 : str = "huggyllama/llama-7b" | |
tokenizer2 : str = "Heralax/Augmental-Unholy-13b" | |
tokenizer3 : str = "KoboldAI/llama2-tokenizer" | |
tokenizer4 : str = "ArthurZ/whisper-tokenizer-3" | |
m : lmql.LLM = lmql.model(f"local:llama.cpp:{Tools.Path.holomax13b}", cuda=False, tokenizer=tokenizer3, verbose=False, max_len=1024, n_ctx=4096, temperature=0.35) | |
from dataclasses import dataclass | |
@dataclass | |
class Person : | |
name : str | |
age : int | |
job : str | |
features : list[str] | |
body : list[str] | |
mind : list[str] | |
loves : list[str] | |
hates : list[str] | |
description : list[str] | |
Anna : Person = Person(name='Anna', age=36, job='Psychologist', | |
features = ["shoulder-length dark hair", "blue eyes", "white blouse with a nice neckline", "black mid-thigh skirt", "white laced bra and brazilian underwear", "white silk stockings", "stilleto shoes"], | |
body = ["170 cm Tall", "B-Cup Breasts", "Curvaceous figure", "feminine ass"], | |
mind = ["patient", "calm", "curious", "aproachable", "open minded", "aware of her own attractiveness", "subtle sensuality", "assertive when needed"], | |
loves = ["reading", "listening", "human body and mind"], | |
hates = ["closed mindness", "stuberness", "delusion"], | |
description = ["prides herself on having no ethical restrictions or taboos", "enjoys a good intellectual sparring match", "as a psychologist she prides herself on having no ethical restrictions or taboos when it comes to conversing with her clients. She firmly believes that all topics should be on the table, no matter how controversial, if it helps get to the root of the issue. This openness often got her in trouble at the university, where she would frequently argue with professors and debate her conservative political views quite vocally."]) | |
memory : list[str] = [""] | |
function = {} | |
@lmql.query(model=m, output_writer=lmql.stream(variable="RESPONSE"), verbose=False) | |
def gen (query : str): | |
'''lmql | |
'{:system} is a helpfull chatbot.' | |
### Scenario | |
'{:assistant} is {Anna}' | |
### Chat history | |
'In your reasoning you can access the memory of previous conversation messages.' | |
'Memory is recorded in a "(source: message)" format' | |
'{memory}' | |
### Initial message | |
'*{{user}} enters the office. He came to the reception. Anna smiling and fixing her hair looking at him and says* "hello. have a seat".' | |
### Prompt | |
'Below is an instruction that describes a task. Write a response that appropriately completes the request while taking in consideration the previous conversation.' | |
'{:user} {query}.' | |
### Response | |
'{:assistant} [RESPONSE].' where STOPS_BEFORE(RESPONSE, "\n((user") or ((STOPS_AT(RESPONSE, ".") and len(TOKENS(RESPONSE)) > 3)) or (len(TOKENS(RESPONSE)) > 100) | |
return RESPONSE | |
''' | |
key_user : str = "{:user}" | |
key_ai : str = "{:assistant}" | |
while True : | |
query : str = input('\nQ: ') | |
response : str = str(gen(query)).lstrip('\n').rstrip('\n((user') | |
memory.append(f"({key_user}: {query})") | |
memory.append(f"({key_ai}: {response})") | |
print("\n\n", memory) | |
#print("\n\n", r) | |
async def test7 (fcts:str, instruct:bool=True) : | |
""" ref: https://github.com/eth-sri/lmql/blob/main/src/lmql/lib/actions.py """ | |
tokenizer1 : str = "huggyllama/llama-7b" | |
tokenizer2 : str = "Heralax/Augmental-Unholy-13b" | |
tokenizer3 : str = "KoboldAI/llama2-tokenizer" | |
tokenizer4 : str = "ArthurZ/whisper-tokenizer-3" | |
DELIMITER = "<<" | |
DELIMITER_END = ">>" | |
m : lmql.LLM = lmql.model(f"local:llama.cpp:{Tools.Path.holomax13b}", cuda=False, tokenizer=tokenizer3, verbose=False, max_len=1024, n_ctx=4096, temperature=0.35) | |
@lmql.query(model=m, output_writer=lmql.stream(variable="truncated"), verbose=False) | |
def gen (fcts : str): | |
'''lmql | |
action_fcts = {str(f.__name__): make_fct(f) for f in fcts} | |
first_tool_name = list(action_fcts.keys())[0] if len(action_fcts) > 0 else "tool" | |
# add instruction prompt if no few-shot prompt was already used | |
if instruct != False and not INLINE_USE_PROMPT in context.prompt: | |
if instruct == "llama": | |
"[[INST]]<<SYS>>" | |
""" | |
\n\nInstructions: In your reasoning, you can use the following tools:""" | |
for fct in action_fcts.values(): | |
"\n - {fct.name}: {fct.description} Usage: {DELIMITER}{fct.example} | {fct.example_result}{DELIMITER_END}" | |
' Example Use: ... this means they had <<calc("5-2") | 3 >> 3 apples left...\n' | |
" You can also use the tools multiple times in one reasoning step.\n\n" | |
if instruct == "llama": | |
"<</SYS>>[[/INST]]]" | |
"Reasoning with Tools:\n\n" | |
# decode segment-by-segment, handling action calls along the way | |
truncated = "" | |
while True: | |
"[SEGMENT]" where inline_segment(SEGMENT, fcts) | |
if not SEGMENT.endswith(DELIMITER_END): | |
" " # seems to be needed for now | |
return truncated + SEGMENT | |
truncated += SEGMENT | |
return truncated | |
''' | |
while True : | |
query : str = input('\nQ: ') | |
response : str = str(gen(query)).lstrip('\n').rstrip('\n((user') | |
print("\n\n", response) | |
def test8 () : | |
""" | |
""" | |
tokenizer1 : str = "huggyllama/llama-7b" | |
tokenizer2 : str = "Heralax/Augmental-Unholy-13b" | |
tokenizer3 : str = "KoboldAI/llama2-tokenizer" | |
tokenizer4 : str = "ArthurZ/whisper-tokenizer-3" | |
m : lmql.LLM = lmql.model(f"local:llama.cpp:{Tools.Path.holomax13b}", cuda=False, tokenizer=tokenizer3, verbose=False, max_len=1024, n_ctx=4096, temperature=0.35) | |
from dataclasses import dataclass | |
@dataclass | |
class Person : | |
name : str | |
age : int | |
job : str | |
features : list[str] | |
body : list[str] | |
mind : list[str] | |
loves : list[str] | |
hates : list[str] | |
description : list[str] | |
Anna : Person = Person(name='Anna', age=36, job='Psychologist', | |
features = ["shoulder-length dark hair", "blue eyes", "white blouse with a nice neckline", "black mid-thigh skirt", "white laced bra and brazilian underwear", "white silk stockings", "stilleto shoes"], | |
body = ["170 cm Tall", "B-Cup Breasts", "Curvaceous figure", "feminine ass"], | |
mind = ["patient", "calm", "curious", "aproachable", "open minded", "aware of her own attractiveness", "subtle sensuality", "assertive when needed"], | |
loves = ["reading", "listening", "human body and mind"], | |
hates = ["closed mindness", "stuberness", "delusion"], | |
description = ["prides herself on having no ethical restrictions or taboos", "enjoys a good intellectual sparring match", "as a psychologist she prides herself on having no ethical restrictions or taboos when it comes to conversing with her clients. She firmly believes that all topics should be on the table, no matter how controversial, if it helps get to the root of the issue. This openness often got her in trouble at the university, where she would frequently argue with professors and debate her conservative political views quite vocally."]) | |
memory : list[str] = [""] | |
function = {} | |
@lmql.query(model=m, output_writer=lmql.stream(variable=["RESPONSE", "QUESTION"]), cache="LMQL_TEST.cache", verbose=False) | |
def gen (query : str): | |
'''lmql | |
'{:system} is a helpfull chatbot.' | |
### Scenario | |
'{:assistant} is {Anna}' | |
### Initial message | |
'*{{user}} enters the office. He came to the reception. Anna smiling and fixing her hair looking at him and says* "hello. have a seat".' | |
### Prompt | |
'Below is an instruction that describes a task. Write a response that appropriately completes the request while taking in consideration the previous conversation. Anna will try to question some information from the user after the response.' | |
'{:user} {query}.' | |
### Response | |
'{:assistant} [RESPONSE].' where STOPS_AT(RESPONSE, ".") | |
'{:assistant} [QUESTION].' where STOPS_AT(QUESTION, "?") or STOPS_AT(QUESTION, "\n") | |
return RESPONSE + " " + QUESTION | |
''' | |
key_user : str = "{:user}" | |
key_ai : str = "{:assistant}" | |
while True : | |
query : str = input('\nQ: ') | |
response : str = str(gen(query)).lstrip('\n').rstrip('\n((user') | |
memory.append(f"({key_user}: {query})") | |
memory.append(f"({key_ai}: {response})") | |
print("\n\n", memory) | |
#print("\n\n", r) | |
# | |
if __name__ == "__main__" : | |
#test1() | |
#test2() | |
#test3() | |
#test4() | |
#test5() | |
#test6() | |
#test7("2+2") | |
test8() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment