From 466f27a714b331db9c622d58b7950cf4f1a177f0 Mon Sep 17 00:00:00 2001 From: Kye Date: Mon, 29 Jan 2024 20:48:06 -0500 Subject: [PATCH] [BUFG] --- README.md | 1 + pyproject.toml | 4 +- swarms/agents/simple_agent.py | 108 ++++++++++---- swarms/cli/_cli.py | 100 +++++-------- swarms/tokenizers/__init__.py | 12 ++ swarms/{models => tokenizers}/r_tokenizers.py | 0 tests/models/test_timm_model.py | 140 +----------------- tests/models/test_ultralytics.py | 8 +- tests/structs/test_swarmnetwork.py | 2 +- 9 files changed, 143 insertions(+), 232 deletions(-) create mode 100644 swarms/tokenizers/__init__.py rename swarms/{models => tokenizers}/r_tokenizers.py (100%) diff --git a/README.md b/README.md index aa8822e8..52fc6a04 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ A modular framework that enables you to Build, Deploy, and Scale Reliable Autono --- ## Usage +With Swarms, you can create structures, such as Agents, Swarms, and Workflows, that are composed of different types of tasks. Let's build a simple creative agent that will dynamically create a 10,000 word blog on health and wellness. Run example in Collab: Open In Colab diff --git a/pyproject.toml b/pyproject.toml index 32eaa71c..74098c43 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "swarms" -version = "3.8.7" +version = "3.8.8" description = "Swarms - Pytorch" license = "MIT" authors = ["Kye Gomez "] @@ -105,4 +105,4 @@ preview = true [tool.poetry.scripts] -swarms = 'swarms.cli._cli:cli' \ No newline at end of file +swarms = 'swarms.cli._cli:main' \ No newline at end of file diff --git a/swarms/agents/simple_agent.py b/swarms/agents/simple_agent.py index 87671c46..757715dd 100644 --- a/swarms/agents/simple_agent.py +++ b/swarms/agents/simple_agent.py @@ -1,40 +1,98 @@ from swarms.structs.conversation import Conversation from swarms.models.base_llm import AbstractLLM +from typing import Any +import importlib +import pkgutil +import swarms.models + + +def get_llm_by_name(name: str): + """ + Searches all the modules exported from the 'swarms.models' path for a class with the given name. + + Args: + name (str): The name of the class to search for. + + Returns: + type: The class with the given name, or None if no such class is found. + """ + for importer, modname, ispkg in pkgutil.iter_modules( + swarms.models.__path__ + ): + module = importlib.import_module(f"swarms.models.{modname}") + if hasattr(module, name): + return getattr(module, name) + return None # Run the language model in a loop for n iterations def SimpleAgent( - llm: AbstractLLM = None, iters: int = 10, *args, **kwargs + llm: AbstractLLM = None, iters: Any = "automatic", *args, **kwargs ): - """Simple agent conversation + """ + A simple agent that interacts with a language model. Args: - llm (_type_): _description_ - iters (int, optional): _description_. Defaults to 10. - - Example: - >>> from swarms.models import GPT2LM - >>> from swarms.agents import SimpleAgent - >>> llm = GPT2LM() - >>> SimpleAgent(llm, iters=10) + llm (AbstractLLM): The language model to use for generating responses. + iters (Any): The number of iterations or "automatic" to run indefinitely. + *args: Additional positional arguments to pass to the language model. + **kwargs: Additional keyword arguments to pass to the language model. + + Raises: + Exception: If the language model is not defined or cannot be found. + + Returns: + None """ + try: + if llm is None: + raise Exception("Language model not defined") + + if isinstance(llm, str): + llm = get_llm_by_name(llm) + if llm is None: + raise Exception(f"Language model {llm} not found") + llm = llm(*args, **kwargs) + except Exception as error: + print(f"[ERROR][SimpleAgent] {error}") + raise error + try: conv = Conversation(*args, **kwargs) - for i in range(iters): - user_input = input("User: ") - conv.add("user", user_input) - if user_input.lower() == "quit": - break - task = ( - conv.return_history_as_string() - ) # Get the conversation history - out = llm(task) - conv.add("assistant", out) - print( - f"Assistant: {out}", - ) - conv.display_conversation() - conv.export_conversation("conversation.txt") + if iters == "automatic": + i = 0 + while True: + user_input = input("\033[91mUser:\033[0m ") + conv.add("user", user_input) + if user_input.lower() == "quit": + break + task = ( + conv.return_history_as_string() + ) # Get the conversation history + out = llm(task, *args, **kwargs) + conv.add("assistant", out) + print( + f"\033[94mAssistant:\033[0m {out}", + ) + conv.display_conversation() + conv.export_conversation("conversation.txt") + i += 1 + else: + for i in range(iters): + user_input = input("\033[91mUser:\033[0m ") + conv.add("user", user_input) + if user_input.lower() == "quit": + break + task = ( + conv.return_history_as_string() + ) # Get the conversation history + out = llm(task, *args, **kwargs) + conv.add("assistant", out) + print( + f"\033[94mAssistant:\033[0m {out}", + ) + conv.display_conversation() + conv.export_conversation("conversation.txt") except Exception as error: print(f"[ERROR][SimpleAgentConversation] {error}") diff --git a/swarms/cli/_cli.py b/swarms/cli/_cli.py index 8dee387f..9b1365ae 100644 --- a/swarms/cli/_cli.py +++ b/swarms/cli/_cli.py @@ -1,75 +1,53 @@ import argparse -import sys +from swarms.agents.simple_agent import SimpleAgent, get_llm_by_name -def cli(): - parser = argparse.ArgumentParser(description="Swarms CLI") - parser.add_argument( - "file_name", help="Python file containing Swarms code to run" - ) - # Help message for the -h flag is automatically generated by argparse - parser.add_argument( - "-v", "--version", action="version", version="%(prog)s 0.1.0" +def main(): + parser = argparse.ArgumentParser( + prog="swarms", + description=( + "Run the SimpleAgent with a specified language model." + ), ) + subparsers = parser.add_subparsers(dest="command") - # Check deployments for a given model - parser.add_argument( - "-c", "--check", help="Check deployments for a given agent" + run_parser = subparsers.add_parser( + "run", help="Run the SimpleAgent." ) - - # Generate an API key for a given agent - parser.add_argument( - "-g", - "--generate", - help="Generate an API key for a given agent", + run_parser.add_argument( + "modelname", + type=str, + help="The name of the language model to use.", ) - - # Signin to swarms with a given API key - parser.add_argument( - "-s", "--signin", help="Signin to swarms with a given API key" + run_parser.add_argument( + "--iters", + type=int, + default="automatic", + help=( + 'Number of iterations or "automatic" for infinite loop.' + ' Defaults to "automatic".' + ), ) - # Signout of swarms - parser.add_argument("-o", "--signout", help="Signout of swarms") - - # List all agents - parser.add_argument("-l", "--list", help="List all agents") - - # List all deployments - parser.add_argument( - "-d", "--deployments", help="List all deployments" + # Add a help command + help_parser = subparsers.add_parser( + "help", help="Show this help message and exit." ) + help_parser.set_defaults(func=lambda args: parser.print_help()) - # Pricing information - parser.add_argument("-p", "--pricing", help="Pricing information") - - # Run a deployment - parser.add_argument("-r", "--run", help="Run a deployment") - - # Stop a deployment - parser.add_argument("-t", "--stop", help="Stop a deployment") - - # Delete a deployment - parser.add_argument("-x", "--delete", help="Delete a deployment") - - # Get a deployment - parser.add_argument("-e", "--get", help="Get a deployment") + args = parser.parse_args() - # Get a deployment's logs - parser.add_argument( - "-z", "--logs", help="Get a deployment's logs" - ) + if hasattr(args, "func"): + args.func(args) + elif args.command == "run": + llm = get_llm_by_name(args.modelname) + if llm is None: + raise ValueError( + "No language model found with name" + f" '{args.modelname}'" + ) + SimpleAgent(llm, iters=args.iters) - # Parse the arguments - args = parser.parse_args() - # Execute the specified file - try: - with open(args.file_name, "r") as file: - exec(file.read(), globals()) - except FileNotFoundError: - print(f"Error: File '{args.file_name}' not found.") - sys.exit(1) - except Exception as e: - print(f"Error executing file '{args.file_name}': {e}") - sys.exit(1) +# if __name__ == "__main__": +# main() diff --git a/swarms/tokenizers/__init__.py b/swarms/tokenizers/__init__.py new file mode 100644 index 00000000..fd60f8cf --- /dev/null +++ b/swarms/tokenizers/__init__.py @@ -0,0 +1,12 @@ +from swarms.tokenizers.r_tokenizers import ( + SentencePieceTokenizer, + HuggingFaceTokenizer, + Tokenizer, +) + + +__all__ = [ + "SentencePieceTokenizer", + "HuggingFaceTokenizer", + "Tokenizer", +] diff --git a/swarms/models/r_tokenizers.py b/swarms/tokenizers/r_tokenizers.py similarity index 100% rename from swarms/models/r_tokenizers.py rename to swarms/tokenizers/r_tokenizers.py diff --git a/tests/models/test_timm_model.py b/tests/models/test_timm_model.py index 97499c6a..0ced344e 100644 --- a/tests/models/test_timm_model.py +++ b/tests/models/test_timm_model.py @@ -1,14 +1,7 @@ from unittest.mock import Mock import torch import pytest -from swarms.models.timm import TimmModel, TimmModelInfo - - -@pytest.fixture -def sample_model_info(): - return TimmModelInfo( - model_name="resnet18", pretrained=True, in_chans=3 - ) +from swarms.models.timm import TimmModel def test_get_supported_models(): @@ -33,45 +26,6 @@ def test_call(sample_model_info): assert isinstance(output_shape, torch.Size) -@pytest.mark.parametrize( - "model_name, pretrained, in_chans", - [ - ("resnet18", True, 3), - ("resnet50", False, 1), - ("efficientnet_b0", True, 3), - ], -) -def test_create_model_parameterized(model_name, pretrained, in_chans): - model_info = TimmModelInfo( - model_name=model_name, - pretrained=pretrained, - in_chans=in_chans, - ) - model_handler = TimmModel() - model = model_handler._create_model(model_info) - assert isinstance(model, torch.nn.Module) - - -@pytest.mark.parametrize( - "model_name, pretrained, in_chans", - [ - ("resnet18", True, 3), - ("resnet50", False, 1), - ("efficientnet_b0", True, 3), - ], -) -def test_call_parameterized(model_name, pretrained, in_chans): - model_info = TimmModelInfo( - model_name=model_name, - pretrained=pretrained, - in_chans=in_chans, - ) - model_handler = TimmModel() - input_tensor = torch.randn(1, in_chans, 224, 224) - output_shape = model_handler.__call__(model_info, input_tensor) - assert isinstance(output_shape, torch.Size) - - def test_get_supported_models_mock(): model_handler = TimmModel() model_handler._get_supported_models = Mock( @@ -88,98 +42,6 @@ def test_create_model_mock(sample_model_info): assert isinstance(model, torch.nn.Module) -def test_call_exception(): - model_handler = TimmModel() - model_info = TimmModelInfo( - model_name="invalid_model", pretrained=True, in_chans=3 - ) - input_tensor = torch.randn(1, 3, 224, 224) - with pytest.raises(Exception): - model_handler.__call__(model_info, input_tensor) - - -def test_coverage(): - pytest.main(["--cov=my_module", "--cov-report=html"]) - - -def test_environment_variable(): - import os - - os.environ["MODEL_NAME"] = "resnet18" - os.environ["PRETRAINED"] = "True" - os.environ["IN_CHANS"] = "3" - - model_handler = TimmModel() - model_info = TimmModelInfo( - model_name=os.environ["MODEL_NAME"], - pretrained=bool(os.environ["PRETRAINED"]), - in_chans=int(os.environ["IN_CHANS"]), - ) - input_tensor = torch.randn(1, model_info.in_chans, 224, 224) - output_shape = model_handler(model_info, input_tensor) - assert isinstance(output_shape, torch.Size) - - -@pytest.mark.slow -def test_marked_slow(): - model_handler = TimmModel() - model_info = TimmModelInfo( - model_name="resnet18", pretrained=True, in_chans=3 - ) - input_tensor = torch.randn(1, 3, 224, 224) - output_shape = model_handler(model_info, input_tensor) - assert isinstance(output_shape, torch.Size) - - -@pytest.mark.parametrize( - "model_name, pretrained, in_chans", - [ - ("resnet18", True, 3), - ("resnet50", False, 1), - ("efficientnet_b0", True, 3), - ], -) -def test_marked_parameterized(model_name, pretrained, in_chans): - model_info = TimmModelInfo( - model_name=model_name, - pretrained=pretrained, - in_chans=in_chans, - ) - model_handler = TimmModel() - model = model_handler._create_model(model_info) - assert isinstance(model, torch.nn.Module) - - -def test_exception_testing(): - model_handler = TimmModel() - model_info = TimmModelInfo( - model_name="invalid_model", pretrained=True, in_chans=3 - ) - input_tensor = torch.randn(1, 3, 224, 224) - with pytest.raises(Exception): - model_handler.__call__(model_info, input_tensor) - - -def test_parameterized_testing(): - model_handler = TimmModel() - model_info = TimmModelInfo( - model_name="resnet18", pretrained=True, in_chans=3 - ) - input_tensor = torch.randn(1, 3, 224, 224) - output_shape = model_handler.__call__(model_info, input_tensor) - assert isinstance(output_shape, torch.Size) - - -def test_use_mocks_and_monkeypatching(): - model_handler = TimmModel() - model_handler._create_model = Mock(return_value=torch.nn.Module()) - model_info = TimmModelInfo( - model_name="resnet18", pretrained=True, in_chans=3 - ) - model = model_handler._create_model(model_info) - assert isinstance(model, torch.nn.Module) - - def test_coverage_report(): # Install pytest-cov # Run tests with coverage report diff --git a/tests/models/test_ultralytics.py b/tests/models/test_ultralytics.py index e90a49db..3e7a7b5c 100644 --- a/tests/models/test_ultralytics.py +++ b/tests/models/test_ultralytics.py @@ -1,11 +1,11 @@ from unittest.mock import patch -from swarms.models.ultralytics_model import Ultralytics +from swarms.models.ultralytics_model import UltralyticsModel def test_ultralytics_init(): with patch("swarms.models.YOLO") as mock_yolo: model_name = "yolov5s" - ultralytics = Ultralytics(model_name) + ultralytics = UltralyticsModel(model_name) mock_yolo.assert_called_once_with(model_name) assert ultralytics.model_name == model_name assert ultralytics.model == mock_yolo.return_value @@ -14,7 +14,7 @@ def test_ultralytics_init(): def test_ultralytics_call(): with patch("swarms.models.YOLO") as mock_yolo: model_name = "yolov5s" - ultralytics = Ultralytics(model_name) + ultralytics = UltralyticsModel(model_name) task = "detect" args = (1, 2, 3) kwargs = {"a": "A", "b": "B"} @@ -28,7 +28,7 @@ def test_ultralytics_call(): def test_ultralytics_list_models(): with patch("swarms.models.YOLO") as mock_yolo: model_name = "yolov5s" - ultralytics = Ultralytics(model_name) + ultralytics = UltralyticsModel(model_name) result = ultralytics.list_models() mock_yolo.list_models.assert_called_once() assert result == mock_yolo.list_models.return_value diff --git a/tests/structs/test_swarmnetwork.py b/tests/structs/test_swarmnetwork.py index 683d3bb8..4844dbcd 100644 --- a/tests/structs/test_swarmnetwork.py +++ b/tests/structs/test_swarmnetwork.py @@ -2,7 +2,7 @@ from unittest.mock import MagicMock, Mock, patch import pytest -from swarm_net import SwarmNet +from swarms.structs.swarm_net import SwarmNet from swarms.structs.agent import Agent from swarms.structs.swarm_net import SwarmNetwork