Skip to content

Commit 91e465e

Browse files
authored
Merge pull request #9 from opentensor/docs-updates
Docs updates
2 parents 44467d1 + a11936a commit 91e465e

File tree

4 files changed

+267
-3
lines changed

4 files changed

+267
-3
lines changed

docs/running_on_staging.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ python neurons/validator.py --netuid 1 --subtensor.chain_endpoint ws://127.0.0.1
167167
```
168168

169169
### 14. Verify your incentive mechanism is running
170-
After a few blocks you validators will set weights this enables the mechanism. Then after the subnet tempo elapses (1000 block ~3hrs ) you should see your incentive mechanism beginning to distribute TAO to your miner.
170+
After a few blocks you validators will set weights this enables the mechanism. Then after the subnet tempo elapses (300 block ~1hrs ) you should see your incentive mechanism beginning to distribute TAO to your miner.
171171
```bash
172172
btcli wallet overview --wallet.name miner --subtensor.chain_endpoint ws://127.0.0.1:9946
173173
```

docs/running_on_testnet.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ miner default 1 True 0.00000 0.00000 0.00000 0.00000 0.00000
104104
Wallet balance: τ0.0
105105
```
106106

107-
10. Edit the default `NETUID=1` and `CHAIN_ENDPOINT=ws://127.0.0.1:9946` arguments in `template/__init__.py` to match your created subnetwork.
107+
12. Edit the default `NETUID=1` and `CHAIN_ENDPOINT=ws://127.0.0.1:9946` arguments in `template/__init__.py` to match your created subnetwork.
108108
Or run the miner and validator directly with the netuid and chain_endpoint arguments.
109109
```bash
110110
# Run the miner with the netuid and chain_endpoint arguments.
@@ -116,5 +116,16 @@ python neurons/validator.py --netuid 1 --subtensor.network test --wallet.name va
116116
>> 2023-08-08 16:58:11.223 | INFO | Running validator for subnet: 1 on network: ws://127.0.0.1:9946 with config: ...
117117
```
118118

119-
7. Stopping Your Nodes:
119+
13. Stopping Your Nodes:
120120
If you want to stop your nodes, you can do so by pressing CTRL + C in the terminal where the nodes are running.
121+
122+
14. Get Emissions Flowing:
123+
Register to the root network using the `btcli`:
124+
```bash
125+
btcli root register --subtensor.network test # ensure on testnet
126+
```
127+
128+
Then set your weights for the subnet:
129+
```bash
130+
btcli root weights --subtensor.network test # ensure on testnet
131+
```

docs/what_are_subnets.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# What is Bittensor?
2+
Bittensor is a network where computers validate the work that other computers contribute to the network - the work what is most valuable to the collective will be rewarded
3+
4+
Bittensor is a catalyst to the open-source developers and smaller AI research labs now have a financial incentive for fine-tuning open foundational models
5+
6+
Bittensor is a library of machine intelligence that continuously grows and shares knowledge amongst peers
7+
8+
# What is a subnet?
9+
10+
Bittensor is releasing its own language for creating incentive mechanisms. This allows developers to build incentive systems on Bittensor, tapping into our web of intelligence to develop markets of the developer’s choosings
11+
12+
Subnet 1, an incentive system for machine intelligence production, showcases the enormous potential of markets to procure huge amounts of resources. Releasing user-created subnets is set to create a cambrian explosion of additional resources into the Bittensor ecosystem
13+
14+
# Why should you care?
15+
16+
As an open-source developer, you now have the ability to write your own incentive mechanisms without creating an entirely new chain. By tapping into Bittensor’s network of intelligence, you can incentivize AI models from all over the world to perform tasks of your choosing (i.e., image generation, storage, compute access, etc.) - the possibilities are truly endless
17+
18+
The release of subnets also offers the potential to pull these tools into a shared network, making all the ingredients necessary to create intelligence available within one network, governed by one token
19+
20+
You get to play a vital role in helping bootstrap what could one day become one of the most powerful networks in the world - and you make money by doing so!
21+
22+
By incentivizing developers to create their own markets, Bittensor is set to become a one-stop-shop for those seeking all the compute requirements for building unstoppable applications on top of an incentivized infrastructure
23+

examples/prompting.ipynb

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": 1,
6+
"metadata": {},
7+
"outputs": [],
8+
"source": [
9+
"\"\"\"\n",
10+
"This notebook is designed to showcase how to build your own subnet, modeled after the \n",
11+
"Bittensor Text Prompting subnet. This subnet is designed to take in a list of messages\n",
12+
"and a list of roles, and generate a completion based on the current state of the network.\n",
13+
"\n",
14+
"To create a subnet, you must define three (3) main elements: \n",
15+
"- the protocol message format (synapse subclass)\n",
16+
"- the miner (how to complete requests)\n",
17+
"- the validator (how to validate requests)\n",
18+
"\n",
19+
"Below is a simple implementation of the protocol, so you can see how it works.\n",
20+
"\n",
21+
"#NOTE: You MUST implement \"{field}_hash\" for any required field in your synapse.\n",
22+
"\n",
23+
"For example, if you have a `messages` field, there must also be a complementary\n",
24+
"`messages_hash` field. This is used to ensure that the data is not tampered with\n",
25+
"during transit. You can use the `required_hash_fields` property to specify which\n",
26+
"fields are required for hash computation.\n",
27+
"\n",
28+
"You can also use the `deserialize` method to specify how to deserialize the data\n",
29+
"into a tensor. This is useful for converting strings into tensors, for example.\n",
30+
"\n",
31+
"You must also define your priority and blacklist functions. See below:\n",
32+
"\"\"\"\n",
33+
"\n",
34+
"\n",
35+
"import bittensor as bt\n",
36+
"import pydantic\n",
37+
"import time\n",
38+
"import torch\n",
39+
"bt.trace()\n",
40+
"\n",
41+
"from typing import List, Dict, Optional, Tuple, Union, Callable\n",
42+
"# Subnet creator controls\n",
43+
"class Prompting( bt.Synapse ):\n",
44+
" \"\"\"\n",
45+
" Represents the core component of a Synapse for handling and controlling message prompting in a network.\n",
46+
" \n",
47+
" The Prompting synapse captures roles and messages, and can generate a completion based on the current state. \n",
48+
" It also contains unique hashes for roles and messages to ensure integrity and uniqueness.\n",
49+
" \n",
50+
" Attributes:\n",
51+
" roles (List[str]): A list of roles associated with this synapse. Immutable post-instantiation.\n",
52+
" messages (List[str]): A list of messages associated with this synapse. Immutable post-instantiation.\n",
53+
" completion (str): A field to store the completion or result after processing.\n",
54+
" messages_hash (str): An immutable hash representing the messages in the prompting scenario.\n",
55+
" roles_hash (str): An immutable hash representing the roles in the prompting scenario.\n",
56+
" \"\"\"\n",
57+
" class Config: validate_assignment = True\n",
58+
" def deserialize( self ): return self.completion\n",
59+
"\n",
60+
" roles: List[str] = pydantic.Field(..., allow_mutation=False)\n",
61+
" messages: List[str] = pydantic.Field(..., allow_mutation=False)\n",
62+
" completion: str = None\n",
63+
"\n",
64+
" messages_hash: str = pydantic.Field(\n",
65+
" \"\",\n",
66+
" title=\"Messages Hash\",\n",
67+
" description=\"Hash of the messages in the Prompting scenario. Immutable.\",\n",
68+
" allow_mutation=False,\n",
69+
" )\n",
70+
"\n",
71+
" roles_hash: str = pydantic.Field(\n",
72+
" \"\",\n",
73+
" title=\"Roles Hash\",\n",
74+
" description=\"Hash of the roles in the Prompting scenario. Immutable.\",\n",
75+
" allow_mutation=False,\n",
76+
" )\n",
77+
"\n",
78+
" @property\n",
79+
" def required_hash_fields(self) -> List[str]:\n",
80+
" \"\"\" Returns the list of fields that are essential for hash computation. \"\"\"\n",
81+
" return ['messages']\n",
82+
"\n",
83+
"def prompt( synapse: Prompting ) -> Prompting:\n",
84+
" \"\"\"\n",
85+
" Process the provided synapse to generate a completion.\n",
86+
"\n",
87+
" Args:\n",
88+
" synapse (Prompting): The input synapse to be processed.\n",
89+
"\n",
90+
" Returns:\n",
91+
" Prompting: The updated synapse with a completion.\n",
92+
" \"\"\"\n",
93+
" bt.logging.debug(\"In prompt!\")\n",
94+
" synapse.completion = \"I am a chatbot\"\n",
95+
" return synapse\n",
96+
"\n",
97+
"def blacklist( synapse: Prompting ) -> Tuple[bool, str]:\n",
98+
" \"\"\"\n",
99+
" Determines if the provided synapse should be blacklisted.\n",
100+
"\n",
101+
" Args:\n",
102+
" synapse (Prompting): The input synapse to be evaluated.\n",
103+
"\n",
104+
" Returns:\n",
105+
" Tuple[bool, str]: A tuple containing a boolean that indicates whether the synapse is blacklisted,\n",
106+
" and a string providing the reason.\n",
107+
" \"\"\"\n",
108+
" return False, \"\"\n",
109+
"\n",
110+
"def priority( synapse: Prompting ) -> float:\n",
111+
" \"\"\"\n",
112+
" Determines the priority of the provided synapse.\n",
113+
"\n",
114+
" Args:\n",
115+
" synapse (Prompting): The input synapse to be evaluated.\n",
116+
"\n",
117+
" Returns:\n",
118+
" float: The priority value of the synapse, with higher values indicating higher priority.\n",
119+
" \"\"\"\n",
120+
" return 0.0\n"
121+
]
122+
},
123+
{
124+
"cell_type": "code",
125+
"execution_count": 2,
126+
"metadata": {},
127+
"outputs": [
128+
{
129+
"name": "stderr",
130+
"output_type": "stream",
131+
"text": [
132+
"INFO: Started server process [2949708]\n",
133+
"INFO: Waiting for application startup.\n",
134+
"TRACE: ASGI [1] Started scope={'type': 'lifespan', 'asgi': {'version': '3.0', 'spec_version': '2.0'}, 'state': {}}\n",
135+
"TRACE: ASGI [1] Receive {'type': 'lifespan.startup'}\n",
136+
"TRACE: ASGI [1] Send {'type': 'lifespan.startup.complete'}\n",
137+
"INFO: Application startup complete.\n",
138+
"ERROR: [Errno 98] error while attempting to bind on address ('0.0.0.0', 8099): address already in use\n",
139+
"INFO: Waiting for application shutdown.\n",
140+
"TRACE: ASGI [1] Receive {'type': 'lifespan.shutdown'}\n",
141+
"TRACE: ASGI [1] Send {'type': 'lifespan.shutdown.complete'}\n",
142+
"TRACE: ASGI [1] Completed\n",
143+
"INFO: Application shutdown complete.\n"
144+
]
145+
},
146+
{
147+
"name": "stdout",
148+
"output_type": "stream",
149+
"text": [
150+
"\u001b[34m2023-09-18 20:37:21.945\u001b[0m | \u001b[36m\u001b[1m TRACE \u001b[0m | Pre-process synapse for request\n",
151+
"\u001b[34m2023-09-18 20:37:21.946\u001b[0m | \u001b[34m\u001b[1m DEBUG \u001b[0m | dendrite | --> | 3837 B | Prompting | 5C86aJ2uQawR6P6veaJQXNK9HaWh6NMbUhTiLs65kq4ZW3NH | 216.153.62.113:8099 | 0 | Success\n",
152+
"\u001b[34m2023-09-18 20:37:21.971\u001b[0m | \u001b[36m\u001b[1m TRACE \u001b[0m | Non-streaming response detected.\n",
153+
"\u001b[34m2023-09-18 20:37:21.972\u001b[0m | \u001b[36m\u001b[1m TRACE \u001b[0m | Postprocess server response \n",
154+
"\u001b[34m2023-09-18 20:37:21.973\u001b[0m | \u001b[34m\u001b[1m DEBUG \u001b[0m | dendrite | <-- | 4391 B | Prompting | 5C86aJ2uQawR6P6veaJQXNK9HaWh6NMbUhTiLs65kq4ZW3NH | 216.153.62.113:8099 | 200 | Success\n"
155+
]
156+
},
157+
{
158+
"data": {
159+
"text/plain": [
160+
"[Prompting(roles=['user'], messages=['hello, who are you?'], completion='I am a chatbot', messages_hash='', roles_hash='')]"
161+
]
162+
},
163+
"execution_count": 2,
164+
"metadata": {},
165+
"output_type": "execute_result"
166+
},
167+
{
168+
"name": "stdout",
169+
"output_type": "stream",
170+
"text": [
171+
"\u001b[34m2023-09-18 20:37:21.973\u001b[0m | \u001b[34m\u001b[1m DEBUG \u001b[0m | dendrite | <-- | 4391 B | Prompting | 5C86aJ2uQawR6P6veaJQXNK9HaWh6NMbUhTiLs65kq4ZW3NH | 216.153.62.113:8099 | 200 | Success\n"
172+
]
173+
}
174+
],
175+
"source": [
176+
"# Create an Axon instance on port 8099.\n",
177+
"axon = bt.axon(port=8099)\n",
178+
"\n",
179+
"# Attach the forward, blacklist, and priority functions to the Axon.\n",
180+
"# forward_fn: The function to handle forwarding logic.\n",
181+
"# blacklist_fn: The function to determine if a request should be blacklisted.\n",
182+
"# priority_fn: The function to determine the priority of the request.\n",
183+
"axon.attach(\n",
184+
" forward_fn=prompt,\n",
185+
" blacklist_fn=blacklist,\n",
186+
" priority_fn=priority\n",
187+
")\n",
188+
"\n",
189+
"# Start the Axon to begin listening for requests.\n",
190+
"axon.start()\n",
191+
"\n",
192+
"# Create a Dendrite instance to handle client-side communication.\n",
193+
"d = bt.dendrite()\n",
194+
"\n",
195+
"# Send a request to the Axon using the Dendrite, passing in a StreamPrompting instance with roles and messages.\n",
196+
"# The response is awaited, as the Dendrite communicates asynchronously with the Axon.\n",
197+
"resp = await d(\n",
198+
" [axon],\n",
199+
" Prompting(roles=[\"user\"], messages=[\"hello, who are you?\"]),\n",
200+
" deserialize=False\n",
201+
")\n",
202+
"\n",
203+
"# The response object contains the result of the prompting operation.\n",
204+
"resp"
205+
]
206+
}
207+
],
208+
"metadata": {
209+
"kernelspec": {
210+
"display_name": "rev2",
211+
"language": "python",
212+
"name": "python3"
213+
},
214+
"language_info": {
215+
"codemirror_mode": {
216+
"name": "ipython",
217+
"version": 3
218+
},
219+
"file_extension": ".py",
220+
"mimetype": "text/x-python",
221+
"name": "python",
222+
"nbconvert_exporter": "python",
223+
"pygments_lexer": "ipython3",
224+
"version": "3.10.12"
225+
},
226+
"orig_nbformat": 4
227+
},
228+
"nbformat": 4,
229+
"nbformat_minor": 2
230+
}

0 commit comments

Comments
 (0)