Skip to content

Commit

Permalink
support tencent hunyuan
Browse files Browse the repository at this point in the history
  • Loading branch information
JiauZhang committed May 23, 2024
1 parent a423c17 commit 3d26677
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
- ✅ 百度文心一言/ERNIE
- ✅ 阿里通义千问/QWen
- ✅ 讯飞星火大模型/Spark
- ✅ 腾讯混元大模型/Hunyuan

### Install
```shell
Expand Down
119 changes: 119 additions & 0 deletions chatchat/tencent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
from chatchat.base import Base
import hashlib, hmac, json, os, sys, time
from datetime import datetime
import httpx

class Completion(Base):
def __init__(self, jfile, model='hunyuan-lite'):
self.model_type = set([
'hunyuan-lite',
'hunyuan-standard',
'hunyuan-standard-256K',
'hunyuan-pro',
])

if model not in self.model_type:
raise RuntimeError(f'supported chat type: {list(self.model_type)}')
self.model = model

self.jfile = jfile
self.jdata = self.load_json(jfile)['tencent']
self.secret_id = self.jdata['secret_id']
self.secret_key = self.jdata['secret_key']
self.host = 'hunyuan.tencentcloudapi.com'
self.endpoint = f'https://{self.host}'
self.client = httpx.Client()

def encode_message(self, jmsg):
# step 1
http_request_method = "POST"
canonical_uri = "/"
canonical_querystring = ""
ct = "application/json; charset=utf-8"
action = 'ChatCompletions'
host = 'hunyuan.tencentcloudapi.com'
payload = json.dumps(jmsg)
canonical_headers = "content-type:%s\nhost:%s\nx-tc-action:%s\n" % (ct, host, action.lower())
signed_headers = "content-type;host;x-tc-action"
hashed_request_payload = hashlib.sha256(payload.encode("utf-8")).hexdigest()
canonical_request = (http_request_method + "\n" +
canonical_uri + "\n" +
canonical_querystring + "\n" +
canonical_headers + "\n" +
signed_headers + "\n" +
hashed_request_payload)

# step 2
service = "hunyuan"
algorithm = "TC3-HMAC-SHA256"
timestamp = int(time.time())
date = datetime.utcfromtimestamp(timestamp).strftime("%Y-%m-%d")
credential_scope = date + "/" + service + "/" + "tc3_request"
hashed_canonical_request = hashlib.sha256(canonical_request.encode("utf-8")).hexdigest()
string_to_sign = (algorithm + "\n" +
str(timestamp) + "\n" +
credential_scope + "\n" +
hashed_canonical_request)

# step 3
def sign(key, msg):
return hmac.new(key, msg.encode("utf-8"), hashlib.sha256).digest()

secret_date = sign(("TC3" + self.secret_key).encode("utf-8"), date)
secret_service = sign(secret_date, service)
secret_signing = sign(secret_service, "tc3_request")
signature = hmac.new(secret_signing, string_to_sign.encode("utf-8"), hashlib.sha256).hexdigest()

# step 4
authorization = (algorithm + " " +
"Credential=" + self.secret_id + "/" + credential_scope + ", " +
"SignedHeaders=" + signed_headers + ", " +
"Signature=" + signature)

headers = {
'Authorization': authorization,
'Content-Type': 'application/json; charset=utf-8',
'Host': self.host,
'X-TC-Action': 'ChatCompletions',
'X-TC-Timestamp': str(timestamp),
'X-TC-Version': '2023-09-01',
'X-TC-Region': 'ap-beijing',
}

return headers, payload

def send_message(self, history: list):
jmsg = {
"TopP": 1,
"Temperature": 1,
"Model": self.model,
"Messages": history,
"Stream": False,
}
headers, payload = self.encode_message(jmsg)
r = self.client.post(self.endpoint, headers=headers, data=payload)
return r.json()

def create(self, message, stream=False):
jmsg = [{
"Role": "user",
"Content": message,
}]
return self.send_message(jmsg)

class Chat(Completion):
def __init__(self, jfile, model='hunyuan-lite', history=[]):
super().__init__(jfile, model=model)
self.history = history

def chat(self, message):
self.history.append({
'Role': 'user',
'Content': message,
})

r = self.send_message(self.history)
assistant_output = r['Response']['Choices'][0]['Message']
self.history.append(assistant_output)

return r
9 changes: 9 additions & 0 deletions examples/tencent_chat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from chatchat.tencent import Chat

chat = Chat('./data.json')
while True:
user = input('user: ')
r = chat.chat(user)
message = r['Response']['Choices'][0]['Message']
print(f"{message['Role']}: {message['Content']}")

24 changes: 24 additions & 0 deletions examples/tencent_completion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from chatchat.tencent import Completion

completion = Completion('./data.json')
r = completion.create('你好!')
# {
# 'Response': {
# 'RequestId': 'xxx',
# 'Note': '以上内容为AI生成 ,不代表开发者立场,请勿删除或修改本标记',
# 'Choices': [{
# 'Message': {
# 'Role': 'assistant',
# 'Content': '您好,有什么可以帮您的吗?'
# }, 'FinishReason': 'stop'
# }],
# 'Created': 111,
# 'Id': 'yyy',
# 'Usage': {
# 'PromptTokens': 222,
# 'CompletionTokens': 333,
# 'TotalTokens': 444
# }
# }
# }
print(r)
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
setup(
name = 'chatchat',
packages = find_packages(exclude=['examples']),
version = '0.1.0',
version = '0.1.1',
license = 'GPL-2.0',
description = 'Large Language Model API',
author = 'JiauZhang',
Expand Down

0 comments on commit 3d26677

Please sign in to comment.