Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BERT Integration! #168

Merged
merged 3 commits into from
Sep 27, 2023
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
51 changes: 51 additions & 0 deletions integrations/bert-base-uncased/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# BERT-BASE Model Integration

## **About BERT-BASE**

BERT base model (uncased) Pretrained model on English language using a masked language modeling (MLM) objective. It was introduced in this paper and first released in this repository. This model is uncased: it does not make a difference between english and English.

## Requirements

- Python (v3.10+ recommended)
- Poetry (A Python packaging and dependency management tool)

## Setup

1. For the demo to work, you need to get HuggingFaceAPI Token:

1. Visit [HuggingFace](https://huggingface.co/).
2. Sign up or log in.
3. Navigate to `Profile -> Settings -> Access Tokens`.
4. Copy an existing token or create a new one.

2. **Install Dependencies**

```bash
poetry install
```

3. **Running The Agent Script**

open terminal goto "bert-base-uncased/src",
run below command to load environment variables and run the agent.

```bash
export HUGGING_FACE_ACCESS_TOKEN="{Your HuggingFaceAPI Token}"
poetry run python agent.py
```

Check the log for "adding bert-base agent to bureau" line and copy the {agent address}.

4. **Running The User Script**

open new terminal and goto "bert-base-uncased/src",
run below command to load environment variables and run the client.

```bash
export BERT_BASE_AGENT_ADDRESS="{ agent address from last step }"
poetry run python client.py
```

After running the command, a request is sent to the agent every 30 sec till its successful.

Modify **INPUT_TEXT** in **bert_base_user.py** to predict a different sentences.
1,226 changes: 1,226 additions & 0 deletions integrations/bert-base-uncased/poetry.lock

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions integrations/bert-base-uncased/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[tool.poetry]
name = "bert-base-uncased-uagent-integration"
version = "0.0.1"
description = "BERT base model (uncased) integration with fetch.ai uagent"
authors = ["Sangram"]

[tool.poetry.dependencies]
python = ">=3.10,<3.12"
uagents = "*"
requests = "^2.31.0"
10 changes: 10 additions & 0 deletions integrations/bert-base-uncased/src/agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from uagents import Bureau

from agents.bert_base_agent import agent


if __name__ == "__main__":
bureau = Bureau(endpoint="http://127.0.0.1:8000/submit", port=8000)
print(f"adding bert-base agent to bureau: {agent.address}")
bureau.add(agent)
bureau.run()
70 changes: 70 additions & 0 deletions integrations/bert-base-uncased/src/agents/bert_base_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
from uagents import Agent, Context, Protocol
from messages.bert_base import PredictionRequest, PredictionResponse, Error
from uagents.setup import fund_agent_if_low
import os
import requests

# Get the HUGGING_FACE_ACCESS_TOKEN from environment variable or default to a placeholder string if not found.
HUGGING_FACE_ACCESS_TOKEN = os.getenv(
"HUGGING_FACE_ACCESS_TOKEN", "HUGGING_FACE_ACCESS_TOKEN")

if HUGGING_FACE_ACCESS_TOKEN == "HUGGING_FACE_ACCESS_TOKEN":
raise Exception(
"You need to provide an HUGGING_FACE_ACCESS_TOKEN, by exporting env, follow README")

BERT_BASE_URL = "https://api-inference.huggingface.co/models/bert-base-uncased"

# Define headers for HTTP request, including content type and authorization details
HEADERS = {
"Authorization": f"Bearer {HUGGING_FACE_ACCESS_TOKEN}"
}

# Create an agent with predefined properties
agent = Agent(
name="bert-base-uncased_agent",
seed=HUGGING_FACE_ACCESS_TOKEN,
port=8000,
endpoint=["http://127.0.0.1:8000/submit"],
)

# Ensure the agent has enough funds
fund_agent_if_low(agent.wallet.address())


async def predict_text(ctx: Context, sender: str, input_text: str):
# Prepare the data
payload = {
"inputs": input_text
}

# Make the POST request and handle possible errors
try:
response = requests.post(BERT_BASE_URL, headers=HEADERS, json=payload)
if response.status_code == 200:
await ctx.send(sender, PredictionResponse(data=f"{response.json()}"))
return
else:
await ctx.send(sender, Error(error=f"Error: {response.json()}"))
return
except Exception as ex:
await ctx.send(sender, Error(error=f"Exception Occurred: {ex}"))
return

# Create an instance of Protocol with a label "BERTBaseUncasedModelAgent"
bert_base_agent = Protocol(name="BERTBaseUncasedModelAgent", version="0.0.1")


@bert_base_agent.on_message(model=PredictionRequest, replies={PredictionResponse, Error})
async def handle_request(ctx: Context, sender: str, request: PredictionRequest):
# Log the request details
ctx.logger.info(f"Got request from {sender}")

await predict_text(ctx, sender, request.masked_text)


# publish_manifest will make the protocol details available on agentverse.
agent.include(bert_base_agent, publish_manifest=True)

# Define the main entry point of the application
if __name__ == "__main__":
bert_base_agent.run()
63 changes: 63 additions & 0 deletions integrations/bert-base-uncased/src/agents/bert_base_user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
from uagents import Agent, Context, Protocol
from messages.bert_base import PredictionRequest, PredictionResponse, Error
from uagents.setup import fund_agent_if_low
import base64
import os
import pprint
import json

# masked sentence you want to predict
INPUT_TEXT = "The goal of life is [MASK]."

BERT_BASE_AGENT_ADDRESS = os.getenv(
"BERT_BASE_AGENT_ADDRESS", "BERT_BASE_AGENT_ADDRESS")

if BERT_BASE_AGENT_ADDRESS == "BERT_BASE_AGENT_ADDRESS":
raise Exception(
"You need to provide an BERT_BASE_AGENT_ADDRESS, by exporting env, check README file")

# Define user agent with specified parameters
user = Agent(
name="bert-base-uncased_user",
port=8001,
endpoint=["http://127.0.0.1:8001/submit"],
)

# Check and top up the agent's fund if low
fund_agent_if_low(user.wallet.address())


@user.on_event("startup")
async def initialize_storage(ctx: Context):
ctx.storage.set("PredictionDone", False)


# Create an instance of Protocol with a label "BERTBaseUncasedModelUser"
bert_base_user = Protocol(name="BERTBaseUncasedModelUser", version="0.0.1")


@bert_base_user.on_interval(period=30, messages=PredictionRequest)
async def predict(ctx: Context):
predictionDone = ctx.storage.get("PredictionDone")

if not predictionDone:
await ctx.send(BERT_BASE_AGENT_ADDRESS, PredictionRequest(masked_text=INPUT_TEXT))


@bert_base_user.on_message(model=PredictionResponse)
async def handle_data(ctx: Context, sender: str, response: PredictionResponse):
# ctx.logger.info(f"predictions: {response.data}")
pprint.pprint(response.data)
ctx.storage.set("PredictionDone", True)


@bert_base_user.on_message(model=Error)
async def handle_error(ctx: Context, sender: str, error: Error):
ctx.logger.info(f"Got error from uagent: {error}")

# publish_manifest will make the protocol details available on agentverse.
user.include(bert_base_user, publish_manifest=True)

# Initiate the task
if __name__ == "__main__":
bert_base_user.run()
8 changes: 8 additions & 0 deletions integrations/bert-base-uncased/src/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from uagents import Bureau
from agents.bert_base_user import user

if __name__ == "__main__":
bureau = Bureau(endpoint="http://127.0.0.1:8001/submit", port=8001)
print(f"adding bert-base user agent to bureau: {user.address}")
bureau.add(user)
bureau.run()
13 changes: 13 additions & 0 deletions integrations/bert-base-uncased/src/messages/bert_base.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from uagents import Model


class PredictionRequest(Model):
masked_text: str


class PredictionResponse(Model):
data: str


class Error(Model):
error: str