Skip to content

Commit

Permalink
together: add chat models, use openai base (#21337)
Browse files Browse the repository at this point in the history
**Description:** Adding chat completions to the Together AI package,
which is our most popular API. Also staying backwards compatible with
the old API so folks can continue to use the completions API as well.
Also moved the embedding API to use the OpenAI library to standardize it
further.

**Twitter handle:** @Nutlope

- [x] **Add tests and docs**: If you're adding a new integration, please
include
- [x] **Lint and test**: Run `make format`, `make lint` and `make test`
from the root of the package(s) you've modified. See contribution
guidelines for more: https://python.langchain.com/docs/contributing/

If no one reviews your PR within a few days, please @-mention one of
baskaryan, efriis, eyurtsev, hwchase17.

---------

Co-authored-by: Erick Friis <[email protected]>
  • Loading branch information
Nutlope and efriis authored May 7, 2024
1 parent a2d3130 commit d6ef5fe
Show file tree
Hide file tree
Showing 22 changed files with 1,494 additions and 466 deletions.
65 changes: 37 additions & 28 deletions docs/docs/integrations/llms/together.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,21 @@
"source": [
"# Together AI\n",
"\n",
"> The Together API makes it easy to fine-tune or run leading open-source models with a couple lines of code. We have integrated the world’s leading open-source models, including Llama-2, RedPajama, Falcon, Alpaca, Stable Diffusion XL, and more. Read more: https://together.ai\n",
"> The Together API makes it easy to query and fine-tune leading open-source models with a couple lines of code. We have integrated the world’s leading open-source models, including Llama-3, Mixtral, DBRX, Stable Diffusion XL, and more. Read more: https://together.ai\n",
"\n",
"To use, you'll need an API key which you can find here:\n",
"https://api.together.xyz/settings/api-keys. This can be passed in as init param\n",
"https://api.together.ai/settings/api-keys. This can be passed in as init param\n",
"``together_api_key`` or set as environment variable ``TOGETHER_API_KEY``.\n",
"\n",
"Together API reference: https://docs.together.ai/reference"
"Together API reference: https://docs.together.ai"
]
},
{
"cell_type": "markdown",
"id": "1c47fc36",
"metadata": {},
"source": []
},
{
"cell_type": "code",
"execution_count": null,
Expand All @@ -28,40 +34,43 @@
},
{
"cell_type": "code",
"execution_count": 3,
"execution_count": null,
"id": "637bb53f",
"metadata": {},
"outputs": [],
"source": [
"# Running chat completions with Together AI\n",
"\n",
"from langchain_core.prompts import ChatPromptTemplate\n",
"from langchain_together import ChatTogether\n",
"\n",
"chat = ChatTogether()\n",
"\n",
"# using chat invoke\n",
"chat.invoke(\"Tell me fun things to do in NYC\")\n",
"\n",
"# using chat stream\n",
"for m in chat.stream(\"Tell me fun things to do in NYC\"):\n",
" print(m)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e7b7170d-d7c5-4890-9714-a37238343805",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"\n",
"A: A large language model is a neural network that is trained on a large amount of text data. It is able to generate text that is similar to the training data, and can be used for tasks such as language translation, question answering, and text summarization.\n",
"\n",
"A: A large language model is a neural network that is trained on a large amount of text data. It is able to generate text that is similar to the training data, and can be used for tasks such as language translation, question answering, and text summarization.\n",
"\n",
"A: A large language model is a neural network that is trained on\n"
]
}
],
"outputs": [],
"source": [
"# Running completions with Together AI\n",
"\n",
"from langchain_together import Together\n",
"\n",
"llm = Together(\n",
" model=\"togethercomputer/RedPajama-INCITE-7B-Base\",\n",
" temperature=0.7,\n",
" max_tokens=128,\n",
" top_k=1,\n",
" model=\"codellama/CodeLlama-70b-Python-hf\",\n",
" # together_api_key=\"...\"\n",
")\n",
"\n",
"input_ = \"\"\"You are a teacher with a deep knowledge of machine learning and AI. \\\n",
"You provide succinct and accurate answers. Answer the following question: \n",
"\n",
"What is a large language model?\"\"\"\n",
"print(llm.invoke(input_))"
"print(llm.invoke(\"def bubble_sort(): \"))"
]
}
],
Expand Down
2 changes: 1 addition & 1 deletion libs/partners/together/LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2023 LangChain, Inc.
Copyright (c) 2024 LangChain, Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
1 change: 0 additions & 1 deletion libs/partners/together/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ integration_test integration_tests: TEST_FILE=tests/integration_tests/
test tests integration_test integration_tests:
poetry run pytest $(TEST_FILE)


######################
# LINTING AND FORMATTING
######################
Expand Down
48 changes: 14 additions & 34 deletions libs/partners/together/README.md
Original file line number Diff line number Diff line change
@@ -1,48 +1,28 @@
# langchain-together

This package contains the LangChain integration for Together's generative models.
This package contains the LangChain integrations for [Together AI](https://www.together.ai/) through their [APIs](https://docs.together.ai/).

## Installation
## Installation and Setup

```sh
- Install the LangChain partner package

```bash
pip install -U langchain-together
```

## Embeddings

You can use Together's embedding models through `TogetherEmbeddings` class.

```py
from langchain_together import TogetherEmbeddings
- Get your Together AI api key from the [Together Dashboard](https://api.together.ai/settings/api-keys) and set it as an environment variable (`TOGETHER_API_KEY`)

embeddings = TogetherEmbeddings(
model='togethercomputer/m2-bert-80M-8k-retrieval'
)
embeddings.embed_query("What is a large language model?")
```

## LLMs
## Chat Completions

You can use Together's generative AI models as Langchain LLMs:
This package contains the `ChatTogether` class, which is the recommended way to interface with Together AI chat models.

```py
from langchain_together import Together
from langchain_core.prompts import PromptTemplate
ADD USAGE EXAMPLE HERE.
Can we add this in the langchain docs?

llm = Together(
model="togethercomputer/RedPajama-INCITE-7B-Base",
temperature=0.7,
max_tokens=64,
top_k=1,
# together_api_key="..."
)
NEED to add image endpoint + completions endpoint as well

template = """Question: {question}
Answer: """
prompt = PromptTemplate.from_template(template)
## Embeddings

chain = prompt | llm
See a [usage example](https://python.langchain.com/docs/integrations/text_embedding/together/)

question = "Who was the president in the year Justin Beiber was born?"
print(chain.invoke({"question": question}))
```
Use `togethercomputer/m2-bert-80M-8k-retrieval` as the default model for embeddings.
8 changes: 2 additions & 6 deletions libs/partners/together/langchain_together/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
from langchain_together.chat_models import ChatTogether
from langchain_together.embeddings import TogetherEmbeddings
from langchain_together.llms import Together
from langchain_together.version import __version__

__all__ = [
"__version__",
"Together",
"TogetherEmbeddings",
]
__all__ = ["ChatTogether", "Together", "TogetherEmbeddings"]
103 changes: 103 additions & 0 deletions libs/partners/together/langchain_together/chat_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
"""Wrapper around Together AI's Chat Completions API."""

import os
from typing import (
Any,
Dict,
List,
Optional,
)

import openai
from langchain_core.pydantic_v1 import Field, SecretStr, root_validator
from langchain_core.utils import (
convert_to_secret_str,
get_from_dict_or_env,
)
from langchain_openai.chat_models.base import BaseChatOpenAI


class ChatTogether(BaseChatOpenAI):
"""ChatTogether chat model.
To use, you should have the environment variable `TOGETHER_API_KEY`
set with your API key or pass it as a named parameter to the constructor.
Example:
.. code-block:: python
from langchain_together import ChatTogether
model = ChatTogether()
"""

@property
def lc_secrets(self) -> Dict[str, str]:
return {"together_api_key": "TOGETHER_API_KEY"}

@classmethod
def get_lc_namespace(cls) -> List[str]:
return ["langchain", "chat_models", "together"]

@property
def lc_attributes(self) -> Dict[str, Any]:
attributes: Dict[str, Any] = {}

if self.together_api_base:
attributes["together_api_base"] = self.together_api_base

return attributes

@property
def _llm_type(self) -> str:
"""Return type of chat model."""
return "together-chat"

model_name: str = Field(default="meta-llama/Llama-3-8b-chat-hf", alias="model")
"""Model name to use."""
together_api_key: Optional[SecretStr] = Field(default=None, alias="api_key")
"""Automatically inferred from env are `TOGETHER_API_KEY` if not provided."""
together_api_base: Optional[str] = Field(
default="https://api.together.ai/v1/chat/completions", alias="base_url"
)

@root_validator()
def validate_environment(cls, values: Dict) -> Dict:
"""Validate that api key and python package exists in environment."""
if values["n"] < 1:
raise ValueError("n must be at least 1.")
if values["n"] > 1 and values["streaming"]:
raise ValueError("n must be 1 when streaming.")

values["together_api_key"] = convert_to_secret_str(
get_from_dict_or_env(values, "together_api_key", "TOGETHER_API_KEY")
)
values["together_api_base"] = values["together_api_base"] or os.getenv(
"TOGETHER_API_BASE"
)

client_params = {
"api_key": (
values["together_api_key"].get_secret_value()
if values["together_api_key"]
else None
),
"base_url": values["together_api_base"],
"timeout": values["request_timeout"],
"max_retries": values["max_retries"],
"default_headers": values["default_headers"],
"default_query": values["default_query"],
}

if not values.get("client"):
sync_specific = {"http_client": values["http_client"]}
values["client"] = openai.OpenAI(
**client_params, **sync_specific
).chat.completions
if not values.get("async_client"):
async_specific = {"http_client": values["http_async_client"]}
values["async_client"] = openai.AsyncOpenAI(
**client_params, **async_specific
).chat.completions
return values
Loading

0 comments on commit d6ef5fe

Please sign in to comment.