community[minor]: Add solar model chat model (#18556)

Add our solar chat models, available model choices:
* solar-1-mini-chat
* solar-1-mini-translate-enko
* solar-1-mini-translate-koen

More documents and pricing can be found at
https://console.upstage.ai/services/solar.

The references to our solar model can be found at
* https://arxiv.org/abs/2402.17032

---------

Co-authored-by: Bagatur <22008038+baskaryan@users.noreply.github.com>
Co-authored-by: Bagatur <baskaryan@gmail.com>
This commit is contained in:
高璟琦 2024-03-29 03:31:11 +08:00 committed by GitHub
parent e576d6c6b4
commit 75173d31db
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 375 additions and 0 deletions

View File

@ -0,0 +1,80 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 5,
"id": "a9667088-04e1-4f67-8221-a0072a2d635f",
"metadata": {
"execution": {
"iopub.execute_input": "2024-03-06T17:04:59.273702Z",
"iopub.status.busy": "2024-03-06T17:04:59.272602Z",
"iopub.status.idle": "2024-03-06T17:05:00.129177Z",
"shell.execute_reply": "2024-03-06T17:05:00.124594Z",
"shell.execute_reply.started": "2024-03-06T17:04:59.273646Z"
}
},
"outputs": [
{
"data": {
"text/plain": [
"AIMessage(content='저는 대형 언어 모델 프로젝트를 구축하고 싶습니다.')"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import os\n",
"\n",
"os.environ[\"SOLAR_API_KEY\"] = \"SOLAR_API_KEY\"\n",
"\n",
"from langchain_community.chat_models.solar import SolarChat\n",
"from langchain_core.messages import HumanMessage, SystemMessage\n",
"\n",
"chat = SolarChat(max_tokens=1024)\n",
"\n",
"messages = [\n",
" SystemMessage(\n",
" content=\"You are a helpful assistant who translates English to Korean.\"\n",
" ),\n",
" HumanMessage(\n",
" content=\"Translate this sentence from English to Korean. I want to build a project of large language model.\"\n",
" ),\n",
"]\n",
"\n",
"chat.invoke(messages)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8cb792fe-2844-4969-a9e9-f4c0f97b1699",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@ -0,0 +1,120 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "2ff00e23-1a90-4a39-b220-83ebfffd96d6",
"metadata": {
"execution": {
"iopub.execute_input": "2024-03-06T17:10:57.375714Z",
"iopub.status.busy": "2024-03-06T17:10:57.375261Z",
"iopub.status.idle": "2024-03-06T17:11:03.473978Z",
"shell.execute_reply": "2024-03-06T17:11:03.472875Z",
"shell.execute_reply.started": "2024-03-06T17:10:57.375670Z"
}
},
"outputs": [
{
"data": {
"text/plain": [
"\"Once upon a time, in a far-off land, there was a young girl named Lily. Lily was a kind and curious girl who loved to explore the world around her. One day, while wandering through the forest, she came across a small, shimmering pond.\\n\\nAs she approached the pond, she saw a beautiful, glowing flower floating on the water's surface. Lily reached out to touch the flower, and as she did, she felt a strange tingling sensation. Suddenly, the flower began to glow even brighter, and Lily was transported to a magical world filled with talking animals and enchanted forests.\\n\\nIn this world, Lily met a wise old owl named Winston who told her that the flower she had touched was a magical one that could grant her any wish she desired. Lily was overjoyed and asked Winston to show her around the magical world.\\n\\nTogether, they explored the enchanted forests, met friendly animals, and discovered hidden treasures. Lily was having the time of her life, but she knew that she couldn't stay in this magical world forever. Eventually, she had to return home.\\n\\nAs she said goodbye to Winston and the magical world, Lily realized that she had learned an important lesson. She had discovered that sometimes, the most magical things in life are the ones that are right in front of us, if we only take the time to look.\\n\\nFrom that day on, Lily always kept her eyes open for the magic in the world around her, and she never forgot the adventure she had in the enchanted forest.\""
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import os\n",
"\n",
"from langchain_community.llms.solar import Solar\n",
"\n",
"os.environ[\"SOLAR_API_KEY\"] = \"SOLAR_API_KEY\"\n",
"llm = Solar()\n",
"llm.invoke(\"tell me a story?\")"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "67fa1711-f08f-43fa-a3bd-75ae5bc6b988",
"metadata": {
"execution": {
"iopub.execute_input": "2024-03-06T17:11:11.359924Z",
"iopub.status.busy": "2024-03-06T17:11:11.358357Z",
"iopub.status.idle": "2024-03-06T17:11:16.692138Z",
"shell.execute_reply": "2024-03-06T17:11:16.686492Z",
"shell.execute_reply.started": "2024-03-06T17:11:11.359835Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/ary/dev/llm/langchain/libs/core/langchain_core/_api/deprecation.py:117: LangChainDeprecationWarning: The function `run` was deprecated in LangChain 0.1.0 and will be removed in 0.2.0. Use invoke instead.\n",
" warn_deprecated(\n"
]
},
{
"data": {
"text/plain": [
"'Step 1: Determine the year Justin Bieber was born.\\nJustin Bieber was born on March 1, 1994.\\n\\nStep 2: Determine the Super Bowl held in 1994.\\nSuper Bowl XXVIII was held in 1994.\\n\\nStep 3: Determine the winning team of Super Bowl XXVIII.\\nThe Dallas Cowboys won Super Bowl XXVIII in 1994.\\n\\nFinal Answer: The Dallas Cowboys won the Super Bowl in the year Justin Bieber was born (1994).'"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from langchain.chains import LLMChain\n",
"from langchain.prompts import PromptTemplate\n",
"from langchain_community.llms.solar import Solar\n",
"\n",
"template = \"\"\"Question: {question}\n",
"\n",
"Answer: Let's think step by step.\"\"\"\n",
"\n",
"prompt = PromptTemplate.from_template(template)\n",
"\n",
"llm = Solar()\n",
"llm_chain = LLMChain(prompt=prompt, llm=llm)\n",
"\n",
"question = \"What NFL team won the Super Bowl in the year Justin Beiber was born?\"\n",
"\n",
"llm_chain.run(question)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "91961983-d0d5-4901-b854-531e158c0416",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

View File

@ -0,0 +1,56 @@
"""Wrapper around Solar chat models."""
from typing import Dict
from langchain_core.pydantic_v1 import root_validator
from langchain_core.utils import get_from_dict_or_env
from langchain_community.chat_models import ChatOpenAI
from langchain_community.llms.solar import SOLAR_SERVICE_URL_BASE, SolarCommon
class SolarChat(SolarCommon, ChatOpenAI):
"""Wrapper around Solar large language models.
To use, you should have the ``openai`` python package installed, and the
environment variable ``SOLAR_API_KEY`` set with your API key.
(Solar's chat API is compatible with OpenAI's SDK.)
Referenced from https://console.upstage.ai/services/solar
Example:
.. code-block:: python
from langchain_community.chat_models.solar import SolarChat
solar = SolarChat(model="solar-1-mini-chat")
"""
@root_validator()
def validate_environment(cls, values: Dict) -> Dict:
"""Validate that the environment is set up correctly."""
values["solar_api_key"] = get_from_dict_or_env(
values, "solar_api_key", "SOLAR_API_KEY"
)
try:
import openai
except ImportError:
raise ImportError(
"Could not import openai python package. "
"Please install it with `pip install openai`."
)
client_params = {
"api_key": values["solar_api_key"],
"base_url": values["base_url"]
if "base_url" in values
else SOLAR_SERVICE_URL_BASE,
}
if not values.get("client"):
values["client"] = openai.OpenAI(**client_params).chat.completions
if not values.get("async_client"):
values["async_client"] = openai.AsyncOpenAI(
**client_params
).chat.completions
return values

View File

@ -0,0 +1,119 @@
from typing import Any, Dict, List, Optional
import requests
from langchain_core.callbacks import CallbackManagerForLLMRun
from langchain_core.language_models import LLM
from langchain_core.pydantic_v1 import BaseModel, Field, SecretStr, root_validator
from langchain_core.utils import convert_to_secret_str, get_from_dict_or_env
from langchain_community.llms.utils import enforce_stop_tokens
SOLAR_SERVICE_URL_BASE = "https://api.upstage.ai/v1/solar"
SOLAR_SERVICE = "https://api.upstage.ai"
class _SolarClient(BaseModel):
"""An API client that talks to the Solar server."""
api_key: SecretStr
"""The API key to use for authentication."""
base_url: str = SOLAR_SERVICE_URL_BASE
def completion(self, request: Any) -> Any:
headers = {"Authorization": f"Bearer {self.api_key.get_secret_value()}"}
response = requests.post(
f"{self.base_url}/chat/completions",
headers=headers,
json=request,
)
if not response.ok:
raise ValueError(f"HTTP {response.status_code} error: {response.text}")
return response.json()["choices"][0]["message"]["content"]
class SolarCommon(BaseModel):
_client: _SolarClient
base_url: str = SOLAR_SERVICE_URL_BASE
solar_api_key: Optional[SecretStr] = Field(default=None, alias="api_key")
"""Solar API key. Get it here: https://console.upstage.ai/services/solar"""
model_name: str = Field(default="solar-1-mini-chat", alias="model")
"""Model name. Available models listed here: https://console.upstage.ai/services/solar"""
max_tokens: int = Field(default=1024, alias="max context")
temperature = 0.3
class Config:
allow_population_by_field_name = True
arbitrary_types_allowed = True
extra = "ignore"
@property
def lc_secrets(self) -> dict:
return {"solar_api_key": "SOLAR_API_KEY"}
@property
def _default_params(self) -> Dict[str, Any]:
return {
"model": self.model_name,
"max_tokens": self.max_tokens,
"temperature": self.temperature,
}
@property
def _invocation_params(self) -> Dict[str, Any]:
return {**{"model": self.model_name}, **self._default_params}
@root_validator(pre=True)
def build_extra(cls, values: Dict[str, Any]) -> Dict[str, Any]:
return values
@root_validator()
def validate_environment(cls, values: Dict) -> Dict:
api_key = get_from_dict_or_env(values, "solar_api_key", "SOLAR_API_KEY")
if api_key is None or len(api_key) == 0:
raise ValueError("SOLAR_API_KEY must be configured")
values["solar_api_key"] = convert_to_secret_str(api_key)
if "base_url" not in values:
values["base_url"] = SOLAR_SERVICE_URL_BASE
if "base_url" in values and not values["base_url"].startswith(SOLAR_SERVICE):
raise ValueError("base_url must match with: " + SOLAR_SERVICE)
values["_client"] = _SolarClient(
api_key=values["solar_api_key"], base_url=values["base_url"]
)
return values
@property
def _llm_type(self) -> str:
return "solar"
class Solar(SolarCommon, LLM):
"""Solar large language models.
To use, you should have the environment variable
``SOLAR_API_KEY`` set with your API key.
Referenced from https://console.upstage.ai/services/solar
"""
class Config:
allow_population_by_field_name = True
def _call(
self,
prompt: str,
stop: Optional[List[str]] = None,
run_manager: Optional[CallbackManagerForLLMRun] = None,
**kwargs: Any,
) -> str:
request = self._invocation_params
request["messages"] = [{"role": "user", "content": prompt}]
request.update(kwargs)
text = self._client.completion(request)
if stop is not None:
# This is required since the stop tokens
# are not enforced by the model parameters
text = enforce_stop_tokens(text, stop)
return text