From 493331371af596226fecb20c876f02ddca71d8f1 Mon Sep 17 00:00:00 2001 From: Dobiichi-Origami <56953648+Dobiichi-Origami@users.noreply.github.com> Date: Mon, 28 Oct 2024 17:21:31 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=B7=E6=96=B0=E7=AE=A1=E6=8E=A7=20API=20?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E5=92=8C=E6=8E=A5=E5=8F=A3=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- python/qianfan/consts.py | 19 +- .../dataset/stress_test/qianfan_llm_load.py | 9 +- python/qianfan/resources/console/charge.py | 114 ++++++++- python/qianfan/resources/console/consts.py | 2 + python/qianfan/resources/console/eval.py | 227 ++++++++++++++++++ python/qianfan/resources/console/finetune.py | 12 + python/qianfan/resources/console/model.py | 4 + python/qianfan/resources/console/service.py | 37 ++- python/qianfan/tests/rpm_and_tpm_test.py | 2 +- 9 files changed, 416 insertions(+), 10 deletions(-) create mode 100644 python/qianfan/resources/console/eval.py diff --git a/python/qianfan/consts.py b/python/qianfan/consts.py index 4c925c35..e209b4ff 100644 --- a/python/qianfan/consts.py +++ b/python/qianfan/consts.py @@ -178,6 +178,14 @@ class Consts: "/wenxinworkshop/modelrepo/eval/result/export/info" ) ModelEvaluableModelListAPI: str = "/wenxinworkshop/modelrepo/eval/model/list" + + ModelEvalV2API: str = "/v2/eval" + ModelEvalV2Create: str = "CreateEvalTask" + ModelEvalV2DescribeTasks: str = "DescribeEvalTasks" + ModelEvalV2DescribeTask: str = "DescribeEvalTask" + ModelEvalV2DescribeTaskReport: str = "DescribeEvalTaskReport" + ModelEvalV2DeleteTask: str = "DeleteEvalTask" + ServiceCreateAPI: str = "/wenxinworkshop/service/apply" ServiceDetailAPI: str = "/wenxinworkshop/service/detail" ServiceListAPI: str = "/wenxinworkshop/service/list" @@ -247,13 +255,16 @@ class Consts: TpmCreditPurchaseQueryParam: str = "PurchaseTPMResource" TpmCreditInfoQueryParam: str = "DescribeTPMResource" TpmCreditStopQueryParam: str = "ReleaseTPMResource" + TpmCreditResizeTPMResourceParam: str = "ResizeTPMResource" + TpmCreditAutoReleaseTPMResourceParam: str = "AutoReleaseTPMResource" PrivateResourceAPI: str = "/v2/charge" PrivateResourcePurchaseParam: str = "PurchaseServiceResource" - PrivateResourceGetResourceListParam: str = "DescribeServiceResources" - PrivateResourceGetResourceParam: str = "DescribeServiceResource" - PrivateResourceReleaseServiceResourceParam: str = "ReleaseServiceResource" - PrivateResourceCreateAutoRenewRulesParam: str = "CreateAutoRenewRules" + PrivateResourceGetResourceListParam: str = "DescribeComputeUnits" + PrivateResourceGetResourceParam: str = "DescribeComputeUnit" + PrivateResourceReleaseServiceResourceParam: str = "ReleaseComputeUnit" + PrivateResourceCreateAutoRenewRulesParam: str = "AutoReleaseComputeUnit" + PrivateResourceResizeComputeUnitParam: str = "ResizeComputeUnit" ChatV2API: str = "/v2/chat/completions" IAMBearerTokenAPI: str = "/v1/BCE-BEARER/token" diff --git a/python/qianfan/dataset/stress_test/qianfan_llm_load.py b/python/qianfan/dataset/stress_test/qianfan_llm_load.py index 940a58ff..d8a9adfc 100644 --- a/python/qianfan/dataset/stress_test/qianfan_llm_load.py +++ b/python/qianfan/dataset/stress_test/qianfan_llm_load.py @@ -6,6 +6,7 @@ import json import re import time +import traceback from typing import Any, Dict, Iterator, Literal, Optional from locust import constant, events, task @@ -269,7 +270,13 @@ def _request_internal( if GlobalData.data["log"] == 1: if self.exc: - self._write_result({"error": str(self.exc)}) + self._write_result( + { + "exception_type": type(self.exc), + "error": str(self.exc), + "stack": "\n".join(traceback.format_tb(self.exc.__traceback__)), + } + ) else: if ( res.get("request", {}).get("headers", {}).get("Authorization", None) diff --git a/python/qianfan/resources/console/charge.py b/python/qianfan/resources/console/charge.py index 329a22ea..5b52ce3b 100644 --- a/python/qianfan/resources/console/charge.py +++ b/python/qianfan/resources/console/charge.py @@ -30,7 +30,7 @@ class Charge(object): @classmethod @console_api_request def charge_tpm_credit( - cls, model: str, purchase_count: int, **kwargs: Any + cls, model: str, purchase_count: int, billing: Dict[str, Any], **kwargs: Any ) -> QfRequest: """ charge the rpm / tpm credit. @@ -40,6 +40,8 @@ def charge_tpm_credit( The model you want to charge to. purchase_count (int): how many credit you want to charge. + billing (Dict[str, Any]): + billing info kwargs (Any): Additional keyword arguments. @@ -54,7 +56,7 @@ def charge_tpm_credit( req.json_body = { "model": model, "purchaseCount": purchase_count, - "billing": {"paymentTiming": "Postpaid"}, + "billing": billing, **kwargs, } return req @@ -66,6 +68,7 @@ def tpm_credit_info( model: str, payment_type: Optional[str] = None, instance_id: Optional[str] = None, + status: Optional[str] = None, **kwargs: Any ) -> QfRequest: """ @@ -79,6 +82,8 @@ def tpm_credit_info( Only available type is "Postpaid" currently. instance_id (Optional[str]): which specific instance you want to get. + status (str): + which status of instance you want to get. **kwargs (Any): Additional keyword arguments. @@ -101,6 +106,9 @@ def tpm_credit_info( if instance_id: req.json_body["instanceId"] = instance_id + if status: + req.json_body["status"] = status + return req @classmethod @@ -135,6 +143,74 @@ def stop_tpm_credit_charging( return req + @classmethod + @console_api_request + def resize_tpm_resource( + cls, instance_id: str, count: Optional[int], **kwargs: Any + ) -> QfRequest: + """ + resize the rpm / tpm charging + + Parameters: + instance_id (str): + which specific instance you want to get. + count: (Optional[int]) + how many tpm resources should be after resize. + **kwargs (Any): + Additional keyword arguments. + + Note: + The `@console_api_request` decorator is applied to this method, enabling it to + send the generated QfRequest and return a QfResponse to the user. + + API Doc: https://cloud.baidu.com/doc/WENXINWORKSHOP/s/cm2cy5ion + """ + + req = QfRequest(method="POST", url=Consts.TpmCreditAPI) + req.query = {"Action": Consts.TpmCreditResizeTPMResourceParam} + req.json_body = { + "instanceId": instance_id, + } + + if count: + req.json_body["count"] = count + + return req + + @classmethod + @console_api_request + def auto_release_tpm_resource( + cls, instance_id: str, release_time: Optional[str], **kwargs: Any + ) -> QfRequest: + """ + resize the rpm / tpm charging + + Parameters: + instance_id (str): + which specific instance you want to get. + release_time: (Optional[str]) + when resources are released automatically. None for cancel + **kwargs (Any): + Additional keyword arguments. + + Note: + The `@console_api_request` decorator is applied to this method, enabling it to + send the generated QfRequest and return a QfResponse to the user. + + API Doc: https://cloud.baidu.com/doc/WENXINWORKSHOP/s/cm2cy5ion + """ + + req = QfRequest(method="POST", url=Consts.TpmCreditAPI) + req.query = {"Action": Consts.TpmCreditAutoReleaseTPMResourceParam} + req.json_body = { + "instanceId": instance_id, + } + + if release_time: + req.json_body["releaseTime"] = release_time + + return req + @classmethod @console_api_request def purchase_service_resource( @@ -172,7 +248,7 @@ def purchase_service_resource( @classmethod @console_api_request - def ger_service_resource_list( + def get_service_resource_list( cls, service_id: str, payment_timing: Optional[str] = None, **kwargs: Any ) -> QfRequest: """ @@ -313,3 +389,35 @@ def create_auto_renew_rules( ) return req + + @classmethod + @console_api_request + def resize_service_resource_count( + cls, instance_id: str, count: int, **kwargs: Any + ) -> QfRequest: + """ + release purchase private service resource from qianfan + + Parameters: + instance_id (str): + The resource instance id. + count (int): + how many instance count you want to set + **kwargs (Any): + other arguments + + Note: + The `@console_api_request` decorator is applied to this method, enabling it to + send the generated QfRequest and return a QfResponse to the user. + + API Doc: https://cloud.baidu.com/doc/WENXINWORKSHOP/s/Tm2cxzmhi + """ + + req = QfRequest(method="POST", url=Consts.PrivateResourceAPI) + req.query = {"Action": Consts.PrivateResourceResizeComputeUnitParam} + req.json_body = { + "count": count, + "instanceId": instance_id, + } + + return req diff --git a/python/qianfan/resources/console/consts.py b/python/qianfan/resources/console/consts.py index 42348514..40ba7555 100644 --- a/python/qianfan/resources/console/consts.py +++ b/python/qianfan/resources/console/consts.py @@ -177,6 +177,8 @@ class TrainMode(str, Enum): """PostPretrain """ DPO = "DPO" """DPO""" + KTO = "KTO" + """KTO""" class TrainParameterScale(str, Enum): diff --git a/python/qianfan/resources/console/eval.py b/python/qianfan/resources/console/eval.py new file mode 100644 index 00000000..5ecf8a38 --- /dev/null +++ b/python/qianfan/resources/console/eval.py @@ -0,0 +1,227 @@ +from typing import Any, Dict, Optional + +from qianfan.consts import Consts +from qianfan.resources.console.utils import _get_console_v2_query, console_api_request +from qianfan.resources.typing import QfRequest + + +class Eval: + class V2: + @classmethod + def base_api_route(cls) -> str: + """ + base api url route for service V2. + + Returns: + str: base api url route + """ + return Consts.ModelEvalV2API + + @classmethod + @console_api_request + def create_eval_task( + cls, + task_name: str, + eval_object_type: str, + eval_object_config: Dict[str, Any], + eval_config: Dict[str, Any], + description: str = "", + **kwargs: Any, + ) -> QfRequest: + """ + create an evaluation task. + + Parameters: + task_name: str, + evaluation task name + eval_object_type: str, + the type of evaluation object + eval_object_config: Dict[str, Any], + info for evaluated object + eval_config: Dict[str, Any], + evaluation config + description: str, + evaluation task description + + kwargs: + Additional keyword arguments that can be passed to customize + the request. + + Note: + The `@console_api_request` decorator is applied to this method, enabling + it to send the generated QfRequest and return a QfResponse to the user. + """ + req = QfRequest( + method="POST", + url=cls.base_api_route(), + query=_get_console_v2_query(Consts.ModelEvalV2Create), + ) + + req.json_body = { + k: v + for k, v in { + **kwargs, + "taskName": task_name, + "evalObjectType": eval_object_type, + "evalObjectConfig": eval_object_config, + "evalConfig": eval_config, + "description": description, + }.items() + if v is not None + } + + return req + + @classmethod + @console_api_request + def describe_eval_tasks( + cls, + eval_type: str, + key_filter: Optional[str] = None, + marker: Optional[str] = None, + max_keys: Optional[int] = None, + page_reverse: Optional[bool] = None, + **kwargs: Any, + ) -> QfRequest: + """ + create an evaluation task. + + Parameters: + eval_type: str, + evaluation task type + key_filter: Optional[str] = None, + a filter field for filtering by task name, id and model version id + marker: Optional[str] = None, + job_id, the marker of the first page. + max_keys: Optional[int] = None, + max keys of the page. + page_reverse: Optional[bool] = None, + page reverse or not. + + kwargs: + Additional keyword arguments that can be passed to customize + the request. + + Note: + The `@console_api_request` decorator is applied to this method, enabling + it to send the generated QfRequest and return a QfResponse to the user. + """ + req = QfRequest( + method="POST", + url=cls.base_api_route(), + query=_get_console_v2_query(Consts.ModelEvalV2DescribeTasks), + ) + + req.json_body = { + k: v + for k, v in { + **kwargs, + "evalType": eval_type, + "keyFilter": key_filter, + "marker": marker, + "maxKeys": max_keys, + "pageReverse": page_reverse, + }.items() + if v is not None + } + + return req + + @classmethod + @console_api_request + def describe_eval_task( + cls, + task_id: str, + **kwargs: Any, + ) -> QfRequest: + """ + create an evaluation task. + + Parameters: + task_id: str, + evaluation task id + + kwargs: + Additional keyword arguments that can be passed to customize + the request. + + Note: + The `@console_api_request` decorator is applied to this method, enabling + it to send the generated QfRequest and return a QfResponse to the user. + """ + req = QfRequest( + method="POST", + url=cls.base_api_route(), + query=_get_console_v2_query(Consts.ModelEvalV2DescribeTask), + json_body={ + "taskId": task_id, + }, + ) + + return req + + @classmethod + @console_api_request + def describe_eval_task_report( + cls, + task_id: str, + **kwargs: Any, + ) -> QfRequest: + """ + create an evaluation task. + + Parameters: + task_id: str, + evaluation task id + + kwargs: + Additional keyword arguments that can be passed to customize + the request. + + Note: + The `@console_api_request` decorator is applied to this method, enabling + it to send the generated QfRequest and return a QfResponse to the user. + """ + req = QfRequest( + method="POST", + url=cls.base_api_route(), + query=_get_console_v2_query(Consts.ModelEvalV2DescribeTaskReport), + json_body={ + "taskId": task_id, + }, + ) + + return req + + @classmethod + @console_api_request + def delete_eval_task( + cls, + task_id: str, + **kwargs: Any, + ) -> QfRequest: + """ + create an evaluation task. + + Parameters: + task_id: str, + evaluation task id + + kwargs: + Additional keyword arguments that can be passed to customize + the request. + + Note: + The `@console_api_request` decorator is applied to this method, enabling + it to send the generated QfRequest and return a QfResponse to the user. + """ + req = QfRequest( + method="POST", + url=cls.base_api_route(), + query=_get_console_v2_query(Consts.ModelEvalV2DeleteTask), + json_body={ + "taskId": task_id, + }, + ) + + return req diff --git a/python/qianfan/resources/console/finetune.py b/python/qianfan/resources/console/finetune.py index 5eab2f99..21effaee 100644 --- a/python/qianfan/resources/console/finetune.py +++ b/python/qianfan/resources/console/finetune.py @@ -176,6 +176,8 @@ def create_job( model: str, train_mode: Union[str, console_consts.TrainMode], description: Optional[str] = None, + parameter_scale: Optional[str] = None, + hyper_parameter_config: Optional[Dict] = None, **kwargs: Any, ) -> QfRequest: """ @@ -195,6 +197,10 @@ def create_job( "PostPreTrain" and so on. description (Optional[str]): The description of the fine-tuning job. + parameter_scale (Optional[str]): + the parameter scale for your fintune model + hyper_parameter_config (Optional[Dict]): + hyper parameter config kwargs: Additional keyword arguments that can be passed to customize the request. @@ -222,6 +228,12 @@ def create_job( ) if description is not None: req.json_body["description"] = description + + if parameter_scale is not None: + req.json_body["parameterScale"] = parameter_scale + + if hyper_parameter_config is not None: + req.json_body["hyperParameterConfig"] = hyper_parameter_config return req @classmethod diff --git a/python/qianfan/resources/console/model.py b/python/qianfan/resources/console/model.py index 4a809788..0631ebce 100644 --- a/python/qianfan/resources/console/model.py +++ b/python/qianfan/resources/console/model.py @@ -1202,6 +1202,7 @@ def describe_model_comp_tasks( marker: Optional[str] = None, max_keys: Optional[int] = None, page_reverse: Optional[bool] = None, + source_model_id: Optional[str] = None, **kwargs: Any, ) -> QfRequest: """ @@ -1216,6 +1217,8 @@ def describe_model_comp_tasks( max keys of the page. page_reverse: Optional[bool] = None, page reverse or not. + source_model_id: Optional[str] = None, + model id for filter. kwargs: Additional keyword arguments that can be passed to customize @@ -1237,6 +1240,7 @@ def describe_model_comp_tasks( "marker": marker, "maxKeys": max_keys, "pageReverse": page_reverse, + "sourceModelId": source_model_id, }.items() if v is not None } diff --git a/python/qianfan/resources/console/service.py b/python/qianfan/resources/console/service.py index bfff9937..c7e72bda 100644 --- a/python/qianfan/resources/console/service.py +++ b/python/qianfan/resources/console/service.py @@ -178,6 +178,12 @@ def service_list( marker: Optional[str] = None, max_keys: Optional[int] = None, page_reverse: Optional[bool] = None, + name: Optional[str] = None, + service_type: Optional[List[str]] = None, + run_status: Optional[List[str]] = None, + creator: Optional[List[str]] = None, + charge_type: Optional[str] = None, + pay_type: Optional[str] = None, **kwargs: Any, ) -> QfRequest: """ @@ -190,6 +196,18 @@ def service_list( max keys of the page. page_reverse: Optional[bool] = None, page reverse or not. + name: Optional[str] = None, + service name for search + service_type: Optional[List[str]] = None, + service type list for search + run_status: Optional[List[str]] = None, + service status list for search + creator: Optional[str] = None, + service creator name for search + charge_type: Optional[str] = None, + service charge type for search + pay_type: Optional[str] = None, + service pay type for search kwargs: Additional keyword arguments that can be passed to customize the request. @@ -210,6 +228,12 @@ def service_list( "marker": marker, "maxKeys": max_keys, "pageReverse": page_reverse, + "name": name, + "serviceType": service_type, + "runStatus": run_status, + "creator": creator, + "chargeType": charge_type, + "payType": pay_type, }.items() if v is not None } @@ -411,6 +435,9 @@ def modify_service( def describe_preset_services( cls, service_ids: Optional[List[str]] = None, + service_type: Optional[List[str]] = None, + charge_type: Optional[List[str]] = None, + charge_status: Optional[List[str]] = None, **kwargs: Any, ) -> QfRequest: """ @@ -419,7 +446,12 @@ def describe_preset_services( Parameters: service_ids: Optional[List[str]] = None, service ids. - + service_type: Optional[List[str]] = None, + service type + charge_type: Optional[List[str]] = None, + charge type + charge_status: Optional[List[str]] = None, + charge status kwargs: Additional keyword arguments that can be passed to customize the request. @@ -438,6 +470,9 @@ def describe_preset_services( for k, v in { **kwargs, "serviceIds": service_ids, + "serviceType": service_type, + "chargeType": charge_type, + "chargeStatus": charge_status, }.items() if v is not None } diff --git a/python/qianfan/tests/rpm_and_tpm_test.py b/python/qianfan/tests/rpm_and_tpm_test.py index a4a70f15..f9fe5df2 100644 --- a/python/qianfan/tests/rpm_and_tpm_test.py +++ b/python/qianfan/tests/rpm_and_tpm_test.py @@ -26,7 +26,7 @@ def test_charge(): model = "ernie-4.0-8k" count = 10 - resp = Charge.charge_tpm_credit(model, count) + resp = Charge.charge_tpm_credit(model, count, {"paymentTiming": "Postpaid"}) assert resp["_request"]["model"] == model assert resp["_request"]["purchaseCount"] == count assert resp["_request"]["billing"]["paymentTiming"] == "Postpaid"