InventorsHub commited on
Commit
110e860
·
verified ·
1 Parent(s): bf90c83

Update bt_generator.py

Browse files
Files changed (1) hide show
  1. bt_generator.py +134 -121
bt_generator.py CHANGED
@@ -1,121 +1,134 @@
1
- from simulator_env import SwarmAgent
2
- from huggingface_hub import hf_hub_download
3
- from llama_cpp import Llama
4
- import textwrap
5
- import re
6
-
7
- # Download only the behavior-tree model shard
8
- model_path = hf_hub_download(
9
- repo_id="Inventors-Hub/SwarmChat-models",
10
- repo_type="model",
11
- filename="Falcon3-10B-Instruct-BehaviorTree-3epochs.Q4_K_M.gguf",
12
- )
13
-
14
-
15
- # llm = Llama(model_path=model_path, n_ctx=1024*4)
16
- llm = Llama(
17
- model_path=model_path,
18
- n_ctx=1024*4, # down from 4096
19
- low_vram=True, # llama.cpp low-vram mode
20
- f16_kv=True, # half-precision kv cache
21
- use_mmap=True, # mmap file
22
- use_mlock=False,
23
- )
24
-
25
- def call_behaviors() -> dict:
26
- behavior_dict = {}
27
- for name, attribute in SwarmAgent.__dict__.items():
28
- if callable(attribute) and not name.startswith("_") \
29
- and not name.startswith("update") and not name.startswith("obstacle"):
30
- doc = attribute.__doc__
31
- if doc is not None:
32
- # Dedent, strip, and join into one line by replacing newlines and tabs
33
- cleaned_doc = " ".join(textwrap.dedent(doc).strip().split())
34
- else:
35
- cleaned_doc = ""
36
- behavior_dict[name] = cleaned_doc
37
- return behavior_dict
38
-
39
- def extract_behavior_tree(response: str) -> str:
40
- """
41
- Extracts an XML behavior tree from the given response text.
42
- Looks for a block of XML enclosed in <root...</root> tags.
43
- """
44
- pattern = re.compile(r'(<root.*?</root>)', re.DOTALL)
45
- match = pattern.search(response)
46
- if match:
47
- return match.group(1).strip()
48
- else:
49
- # If no valid XML block is found, return the original response.
50
- return response.strip()
51
-
52
- def save_behavior_tree(tree_xml: str, file_name: str = "tree.xml") -> None:
53
- """
54
- Saves the behavior tree XML to a file.
55
- """
56
- with open(file_name, "w", encoding="utf-8") as f:
57
- f.write(tree_xml)
58
-
59
-
60
- def construct_prompt(prompt: str, prompt_type: str="one") -> str:
61
-
62
- behaviors = call_behaviors()
63
- behaviors_text = "\n".join(f"{name}: {doc}" for name, doc in behaviors.items())
64
-
65
- plan_prompt = f"""
66
- <s>
67
- <<SYS>>You are a helpful, respectful, and honest AI assistant. Your task is to generate well-structured XML code for behavior trees based on the provided instructions.<</SYS>>
68
- INSTRUCTIONS: It is CRITICAL to use only the following behaviors structured as a dictionary: {behaviors_text} to construct behavior tree in XML format for the following command. Including any behavior that is not in the provided dictionary can result in damage to the agents and potentially humans, therefore you are not allowed to do so. AVOID AT ALL COSTS.
69
- USER COMMAND: generate behavior tree to "{prompt}". Take a step back and think deeply about the behavior you need for this command. Consider the XML structure and the behaviors you use.
70
- The output MUST follow this XML structure exactly, including:
71
- - A root element with <root BTCPP_format and main_tree_to_execute attributes.
72
- - A <BehaviorTree> element with an inner structure of Sequences, Fallback, Conditions, and Actions.
73
- - A <TreeNodesModel> section listing all node models.
74
- - No additional text or commentary outside the XML.
75
- Output only the XML behavior tree without extra text.
76
- OUTPUT:
77
- """
78
-
79
- if prompt_type == "zero":
80
- return plan_prompt
81
- elif prompt_type == "one":
82
- path = "Prompt_One_shot.txt"
83
- with open(path, "r", encoding="utf-8") as file:
84
- file_content = file.read()
85
- return f"{file_content} {plan_prompt}"
86
- elif prompt_type == "two":
87
- path = "Prompt_Two_Shot.txt"
88
- with open(path, "r", encoding="utf-8") as file:
89
- file_content = file.read()
90
- return f"{file_content} {plan_prompt}"
91
- else:
92
- raise ValueError("Unknown prompt type provided.")
93
-
94
-
95
- def generate_behavior_tree(task_prompt: str) -> str:
96
-
97
- prompt = construct_prompt(task_prompt)
98
-
99
- print("\n\n",prompt,"\n\n")
100
-
101
- output = llm(
102
- prompt,
103
- temperature=0,
104
- max_tokens=1024,
105
- top_p=0.95,
106
- top_k=50,
107
- repeat_penalty=1.1
108
- )
109
- response = output.get("choices", [{}])[0].get("text", "").strip()
110
- tree_xml = extract_behavior_tree(response)
111
- save_behavior_tree(tree_xml)
112
- print("\n response: \n", response)
113
- return tree_xml
114
-
115
-
116
- # Example usage:
117
- if __name__ == "__main__":
118
- task = "Generate a behavior tree to just form a line."
119
- response = generate_behavior_tree(task)
120
- print("Generated behavior tree response:")
121
- print(response)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from simulator_env import SwarmAgent
2
+ from huggingface_hub import hf_hub_download
3
+ from llama_cpp import Llama
4
+ import textwrap
5
+ import re
6
+
7
+ # Download only the behavior-tree model shard
8
+ model_path = hf_hub_download(
9
+ repo_id="Inventors-Hub/SwarmChat-models",
10
+ repo_type="model",
11
+ filename="Falcon3-10B-Instruct-BehaviorTree-3epochs.Q4_K_M.gguf",
12
+ )
13
+
14
+
15
+ # llm = Llama(model_path=model_path, n_ctx=1024*4)
16
+ # llm = Llama(
17
+ # model_path=model_path,
18
+ # n_ctx=1024*4, # down from 4096
19
+ # low_vram=True, # llama.cpp low-vram mode
20
+ # f16_kv=True, # half-precision kv cache
21
+ # use_mmap=True, # mmap file
22
+ # use_mlock=False,
23
+ # )
24
+ llm = None
25
+
26
+ @spaces.GPU
27
+ def gpu_llm():
28
+ llm = Llama(
29
+ model_path=model_path,
30
+ n_ctx=1024*4, # down from 4096
31
+ low_vram=True, # llama.cpp low-vram mode
32
+ f16_kv=True, # half-precision kv cache
33
+ use_mmap=True, # mmap file
34
+ use_mlock=False,
35
+ )
36
+ return llm
37
+
38
+ def call_behaviors() -> dict:
39
+ behavior_dict = {}
40
+ for name, attribute in SwarmAgent.__dict__.items():
41
+ if callable(attribute) and not name.startswith("_") \
42
+ and not name.startswith("update") and not name.startswith("obstacle"):
43
+ doc = attribute.__doc__
44
+ if doc is not None:
45
+ # Dedent, strip, and join into one line by replacing newlines and tabs
46
+ cleaned_doc = " ".join(textwrap.dedent(doc).strip().split())
47
+ else:
48
+ cleaned_doc = ""
49
+ behavior_dict[name] = cleaned_doc
50
+ return behavior_dict
51
+
52
+ def extract_behavior_tree(response: str) -> str:
53
+ """
54
+ Extracts an XML behavior tree from the given response text.
55
+ Looks for a block of XML enclosed in <root...</root> tags.
56
+ """
57
+ pattern = re.compile(r'(<root.*?</root>)', re.DOTALL)
58
+ match = pattern.search(response)
59
+ if match:
60
+ return match.group(1).strip()
61
+ else:
62
+ # If no valid XML block is found, return the original response.
63
+ return response.strip()
64
+
65
+ def save_behavior_tree(tree_xml: str, file_name: str = "tree.xml") -> None:
66
+ """
67
+ Saves the behavior tree XML to a file.
68
+ """
69
+ with open(file_name, "w", encoding="utf-8") as f:
70
+ f.write(tree_xml)
71
+
72
+
73
+ def construct_prompt(prompt: str, prompt_type: str="one") -> str:
74
+
75
+ behaviors = call_behaviors()
76
+ behaviors_text = "\n".join(f"{name}: {doc}" for name, doc in behaviors.items())
77
+
78
+ plan_prompt = f"""
79
+ <s>
80
+ <<SYS>>You are a helpful, respectful, and honest AI assistant. Your task is to generate well-structured XML code for behavior trees based on the provided instructions.<</SYS>>
81
+ INSTRUCTIONS: It is CRITICAL to use only the following behaviors structured as a dictionary: {behaviors_text} to construct behavior tree in XML format for the following command. Including any behavior that is not in the provided dictionary can result in damage to the agents and potentially humans, therefore you are not allowed to do so. AVOID AT ALL COSTS.
82
+ USER COMMAND: generate behavior tree to "{prompt}". Take a step back and think deeply about the behavior you need for this command. Consider the XML structure and the behaviors you use.
83
+ The output MUST follow this XML structure exactly, including:
84
+ - A root element with <root BTCPP_format and main_tree_to_execute attributes.
85
+ - A <BehaviorTree> element with an inner structure of Sequences, Fallback, Conditions, and Actions.
86
+ - A <TreeNodesModel> section listing all node models.
87
+ - No additional text or commentary outside the XML.
88
+ Output only the XML behavior tree without extra text.
89
+ OUTPUT:
90
+ """
91
+
92
+ if prompt_type == "zero":
93
+ return plan_prompt
94
+ elif prompt_type == "one":
95
+ path = "Prompt_One_shot.txt"
96
+ with open(path, "r", encoding="utf-8") as file:
97
+ file_content = file.read()
98
+ return f"{file_content} {plan_prompt}"
99
+ elif prompt_type == "two":
100
+ path = "Prompt_Two_Shot.txt"
101
+ with open(path, "r", encoding="utf-8") as file:
102
+ file_content = file.read()
103
+ return f"{file_content} {plan_prompt}"
104
+ else:
105
+ raise ValueError("Unknown prompt type provided.")
106
+
107
+
108
+ def generate_behavior_tree(task_prompt: str) -> str:
109
+
110
+ prompt = construct_prompt(task_prompt)
111
+
112
+ print("\n\n",prompt,"\n\n")
113
+
114
+ output = llm(
115
+ prompt,
116
+ temperature=0,
117
+ max_tokens=1024,
118
+ top_p=0.95,
119
+ top_k=50,
120
+ repeat_penalty=1.1
121
+ )
122
+ response = output.get("choices", [{}])[0].get("text", "").strip()
123
+ tree_xml = extract_behavior_tree(response)
124
+ save_behavior_tree(tree_xml)
125
+ print("\n response: \n", response)
126
+ return tree_xml
127
+
128
+
129
+ # Example usage:
130
+ if __name__ == "__main__":
131
+ task = "Generate a behavior tree to just form a line."
132
+ response = generate_behavior_tree(task)
133
+ print("Generated behavior tree response:")
134
+ print(response)