Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 27 additions & 130 deletions examples/prompting.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -26,64 +26,14 @@
"\n",
"\n",
"import bittensor as bt\n",
"bt.trace()\n",
"\n",
"import pydantic\n",
"import time\n",
"import torch\n",
"bt.trace()\n",
"\n",
"from typing import List, Dict, Optional, Tuple, Union, Callable\n",
"# Subnet creator controls\n",
"class Prompting( bt.Synapse ):\n",
" \"\"\"\n",
" Represents the core component of a Synapse for handling and controlling message prompting in a network.\n",
" \n",
" The Prompting synapse captures roles and messages, and can generate a completion based on the current state. \n",
" It also contains unique hashes for roles and messages to ensure integrity and uniqueness.\n",
" \n",
" Attributes:\n",
" roles (List[str]): A list of roles associated with this synapse. Immutable post-instantiation.\n",
" messages (List[str]): A list of messages associated with this synapse. Immutable post-instantiation.\n",
" completion (str): A field to store the completion or result after processing.\n",
" \"\"\"\n",
" class Config: validate_assignment = True\n",
" def deserialize( self ): return self.completion\n",
"\n",
" # Roles is a list of strings defining the role for the LLM server to generate.\n",
" # For example ['system', 'user', 'assistant'].\n",
" roles: List[str] = pydantic.Field(\n",
" ...,\n",
" title=\"Roles\",\n",
" description=\"A list of roles in the Prompting scenario. Immuatable.\",\n",
" allow_mutation=False,\n",
" )\n",
"from typing import List, Tuple, Optional, Any\n",
"from prompting.protocol import Prompting as Prompting\n",
"\n",
" # Defines the messages that will be passed to the server. This field is where the\n",
" # actual content (body) will go for the prompts and user queries.\n",
" messages: List[str] = pydantic.Field(\n",
" ...,\n",
" title=\"Messages\",\n",
" description=\"A list of messages in the Prompting scenario. Immutable.\",\n",
" allow_mutation=False,\n",
" )\n",
" \n",
" # Defines the `completion` field, which will store the result after processing.\n",
" # By default, it is empty string \"\" until a value is assigned to it by the miner.\n",
" completion: str = pydantic.Field(\n",
" \"\",\n",
" title=\"Completion\",\n",
" description=\"Completion status of the current Prompting object. This attribute is mutable and can be updated.\",\n",
" )\n",
"\n",
" @property\n",
" def required_hash_fields(self) -> List[str]:\n",
" \"\"\"\n",
" Returns the list of fields that are essential for hash computation.\n",
" \n",
" This is controlled by the subnet operator and can be minimally pared down to only\n",
" essential body content that needs to be validated for each request. For text-prompting\n",
" `roles` is not really relevant, but the `messages` are in this case.\n",
" \"\"\"\n",
" return ['messages']\n",
"\n",
"def prompt( synapse: Prompting ) -> Prompting:\n",
" \"\"\"\n",
Expand Down Expand Up @@ -127,14 +77,14 @@
},
{
"cell_type": "code",
"execution_count": 2,
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"INFO: Started server process [3088652]\n",
"INFO: Started server process [357698]\n",
"INFO: Waiting for application startup.\n",
"TRACE: ASGI [1] Started scope={'type': 'lifespan', 'asgi': {'version': '3.0', 'spec_version': '2.0'}, 'state': {}}\n",
"TRACE: ASGI [1] Receive {'type': 'lifespan.startup'}\n",
Expand All @@ -147,152 +97,98 @@
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[34m2023-09-19 02:12:06.962\u001b[0m | \u001b[36m\u001b[1m TRACE \u001b[0m | Pre-process synapse for request\n"
"\u001b[34m2023-10-01 18:08:34.428\u001b[0m | \u001b[34m\u001b[1m DEBUG \u001b[0m | dendrite | --> | 3940 B | Prompting | 5C86aJ2uQawR6P6veaJQXNK9HaWh6NMbUhTiLs65kq4ZW3NH | 149.137.225.62:8099 | 0 | Success\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"TRACE: 127.0.0.1:43048 - HTTP connection made\n"
"TRACE: 127.0.0.1:53564 - HTTP connection made\n",
"TRACE: 127.0.0.1:53564 - ASGI [2] Started scope={'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8099), 'client': ('127.0.0.1', 53564), 'scheme': 'http', 'method': 'POST', 'root_path': '', 'path': '/Prompting', 'raw_path': b'/Prompting', 'query_string': b'', 'headers': '<...>', 'state': {}}\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[34m2023-09-19 02:12:06.962\u001b[0m | \u001b[34m\u001b[1m DEBUG \u001b[0m | dendrite | --> | 3837 B | Prompting | 5C86aJ2uQawR6P6veaJQXNK9HaWh6NMbUhTiLs65kq4ZW3NH | 216.153.62.113:8099 | 0 | Success\n"
"\u001b[34m2023-10-01 18:08:34.442\u001b[0m | \u001b[34m\u001b[1m DEBUG \u001b[0m | axon | <-- | 875 B | Prompting | 5C86aJ2uQawR6P6veaJQXNK9HaWh6NMbUhTiLs65kq4ZW3NH | 127.0.0.1:53564 | 200 | Success \n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"TRACE: 127.0.0.1:43048 - ASGI [2] Started scope={'type': 'http', 'asgi': {'version': '3.0', 'spec_version': '2.3'}, 'http_version': '1.1', 'server': ('127.0.0.1', 8099), 'client': ('127.0.0.1', 43048), 'scheme': 'http', 'method': 'POST', 'root_path': '', 'path': '/Prompting', 'raw_path': b'/Prompting', 'query_string': b'', 'headers': '<...>', 'state': {}}\n"
"TRACE: 127.0.0.1:53564 - ASGI [2] Receive {'type': 'http.request', 'body': '<875 bytes>', 'more_body': False}\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[34m2023-09-19 02:12:06.978\u001b[0m | \u001b[36m\u001b[1m TRACE \u001b[0m | request.headers Headers({'host': '0.0.0.0:8099', 'name': 'Prompting', 'timeout': '12.0', 'bt_header_axon_ip': '216.153.62.113', 'bt_header_axon_port': '8099', 'bt_header_axon_hotkey': '5C86aJ2uQawR6P6veaJQXNK9HaWh6NMbUhTiLs65kq4ZW3NH', 'bt_header_dendrite_ip': '216.153.62.113', 'bt_header_dendrite_version': '600', 'bt_header_dendrite_nonce': '2965315063849355', 'bt_header_dendrite_uuid': 'eea38ac4-5691-11ee-8416-56c4f4c1dac3', 'bt_header_dendrite_hotkey': '5C86aJ2uQawR6P6veaJQXNK9HaWh6NMbUhTiLs65kq4ZW3NH', 'bt_header_dendrite_signature': '0x18e44fcd52477c8c5bdb86a8255198dd83d78ceb97160194e7116945696b8f29e05bb129aef65ac0c0a9c86d36710b9fb18570f38ec2a097e515db70f96f3b8d', 'bt_header_input_obj_roles': 'W10=', 'bt_header_input_hash_roles': '70462836afeca889fed38157ba64b3ae1298b87f08270130a9c33704fc901c58', 'bt_header_input_obj_messages': 'W10=', 'bt_header_input_hash_messages': '13559dc1af7acbfb7f134eca00c24bbb0893b83c1199badde4da7e4b7421cb79', 'header_size': '640', 'total_size': '3865', 'accept': '*/*', 'accept-encoding': 'gzip, deflate', 'user-agent': 'Python/3.10 aiohttp/3.8.5', 'content-length': '852', 'content-type': 'application/json'})\n",
"\u001b[34m2023-09-19 02:12:06.978\u001b[0m | \u001b[34m\u001b[1m DEBUG \u001b[0m | axon | <-- | 852 B | Prompting | 5C86aJ2uQawR6P6veaJQXNK9HaWh6NMbUhTiLs65kq4ZW3NH | 127.0.0.1:43048 | 200 | Success \n"
"\u001b[34m2023-10-01 18:08:34.445\u001b[0m | \u001b[34m\u001b[1m DEBUG \u001b[0m | In prompt! \n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"TRACE: 127.0.0.1:43048 - ASGI [2] Receive {'type': 'http.request', 'body': '<852 bytes>', 'more_body': False}\n"
"TRACE: 127.0.0.1:53564 - ASGI [2] Send {'type': 'http.response.start', 'status': 200, 'headers': '<...>'}\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[34m2023-09-19 02:12:06.979\u001b[0m | \u001b[36m\u001b[1m TRACE \u001b[0m | Check Blacklist \n",
"\u001b[34m2023-09-19 02:12:06.979\u001b[0m | \u001b[36m\u001b[1m TRACE \u001b[0m | Run priority \n",
"\u001b[34m2023-09-19 02:12:06.981\u001b[0m | \u001b[36m\u001b[1m TRACE \u001b[0m | Check verification \n"
"\u001b[34m2023-10-01 18:08:34.452\u001b[0m | \u001b[34m\u001b[1m DEBUG \u001b[0m | axon | --> | 830 B | Prompting | 5C86aJ2uQawR6P6veaJQXNK9HaWh6NMbUhTiLs65kq4ZW3NH | 127.0.0.1:53564 | 200 | Success\n",
"INFO: 127.0.0.1:53564 - \"POST /Prompting HTTP/1.1\" 200 OK\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"TRACE: 127.0.0.1:43048 - ASGI [2] Send {'type': 'http.response.start', 'status': 200, 'headers': '<...>'}\n"
"TRACE: 127.0.0.1:53564 - ASGI [2] Send {'type': 'http.response.body', 'body': '<830 bytes>', 'more_body': True}\n",
"TRACE: 127.0.0.1:53564 - ASGI [2] Send {'type': 'http.response.body', 'body': '<0 bytes>', 'more_body': False}\n",
"TRACE: 127.0.0.1:53564 - ASGI [2] Receive {'type': 'http.disconnect'}\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"INFO: 127.0.0.1:43048 - \"POST /Prompting HTTP/1.1\" 200 OK\n",
"\u001b[34m2023-09-19 02:12:06.981\u001b[0m | \u001b[34m\u001b[1m DEBUG \u001b[0m | loading body to json \n",
"\u001b[34m2023-09-19 02:12:06.982\u001b[0m | \u001b[34m\u001b[1m DEBUG \u001b[0m | Checking messages \n"
"\u001b[34m2023-10-01 18:08:34.456\u001b[0m | \u001b[34m\u001b[1m DEBUG \u001b[0m | dendrite | <-- | 4494 B | Prompting | 5C86aJ2uQawR6P6veaJQXNK9HaWh6NMbUhTiLs65kq4ZW3NH | 149.137.225.62:8099 | 200 | Success\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"TRACE: 127.0.0.1:43048 - ASGI [2] Send {'type': 'http.response.body', 'body': '<805 bytes>', 'more_body': True}\n"
"TRACE: 127.0.0.1:53564 - ASGI [2] Completed\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[34m2023-09-19 02:12:06.982\u001b[0m | \u001b[36m\u001b[1m TRACE \u001b[0m | Run forward \n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"TRACE: 127.0.0.1:43048 - ASGI [2] Send {'type': 'http.response.body', 'body': '<0 bytes>', 'more_body': False}\n"
"\u001b[34m2023-10-01 18:08:34.456\u001b[0m | \u001b[34m\u001b[1m DEBUG \u001b[0m | dendrite | <-- | 4494 B | Prompting | 5C86aJ2uQawR6P6veaJQXNK9HaWh6NMbUhTiLs65kq4ZW3NH | 149.137.225.62:8099 | 200 | Success\n"
]
},
{
"data": {
"text/plain": [
"[Prompting(roles=['user'], messages=['hello, who are you?'], completion='I am a chatbot', messages_hash='', roles_hash='')]"
"[Prompting(required_hash_fields=['messages'], roles=['user'], messages=['hello, who are you?'], completion='I am a chatbot')]"
]
},
"execution_count": 2,
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[34m2023-09-19 02:12:06.984\u001b[0m | \u001b[34m\u001b[1m DEBUG \u001b[0m | In prompt! \n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"TRACE: 127.0.0.1:43048 - ASGI [2] Receive {'type': 'http.disconnect'}\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[34m2023-09-19 02:12:06.987\u001b[0m | \u001b[36m\u001b[1m TRACE \u001b[0m | Fill successful response \n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"TRACE: 127.0.0.1:43048 - ASGI [2] Completed\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[34m2023-09-19 02:12:06.992\u001b[0m | \u001b[36m\u001b[1m TRACE \u001b[0m | Finally \n",
"\u001b[34m2023-09-19 02:12:06.993\u001b[0m | \u001b[34m\u001b[1m DEBUG \u001b[0m | axon | --> | 805 B | Prompting | 5C86aJ2uQawR6P6veaJQXNK9HaWh6NMbUhTiLs65kq4ZW3NH | 127.0.0.1:43048 | 200 | Success\n",
"\u001b[34m2023-09-19 02:12:06.995\u001b[0m | \u001b[36m\u001b[1m TRACE \u001b[0m | Non-streaming response detected.\n",
"\u001b[34m2023-09-19 02:12:06.997\u001b[0m | \u001b[36m\u001b[1m TRACE \u001b[0m | Postprocess server response \n",
"\u001b[34m2023-09-19 02:12:06.998\u001b[0m | \u001b[34m\u001b[1m DEBUG \u001b[0m | dendrite | <-- | 4391 B | Prompting | 5C86aJ2uQawR6P6veaJQXNK9HaWh6NMbUhTiLs65kq4ZW3NH | 216.153.62.113:8099 | 200 | Success\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\u001b[34m2023-09-19 02:12:06.998\u001b[0m | \u001b[34m\u001b[1m DEBUG \u001b[0m | dendrite | <-- | 4391 B | Prompting | 5C86aJ2uQawR6P6veaJQXNK9HaWh6NMbUhTiLs65kq4ZW3NH | 216.153.62.113:8099 | 200 | Success\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"TRACE: 127.0.0.1:43048 - HTTP connection lost\n"
"TRACE: 127.0.0.1:53564 - HTTP connection lost\n"
]
}
],
Expand All @@ -304,10 +200,11 @@
"# forward_fn: The function to handle forwarding logic.\n",
"# blacklist_fn: The function to determine if a request should be blacklisted.\n",
"# priority_fn: The function to determine the priority of the request.\n",
"# required_hash_fields: The fields that must be present in the request hash.\n",
"axon.attach(\n",
" forward_fn=prompt,\n",
" blacklist_fn=blacklist,\n",
" priority_fn=priority\n",
" priority_fn=priority,\n",
")\n",
"\n",
"# Start the Axon to begin listening for requests.\n",
Expand Down Expand Up @@ -345,7 +242,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
"version": "3.10.13"
},
"orig_nbformat": 4
},
Expand Down
Loading