diff --git a/src/Cnblogs.DashScope.Core/IMaxTokenParameter.cs b/src/Cnblogs.DashScope.Core/IMaxTokenParameter.cs new file mode 100644 index 0000000..eb89dae --- /dev/null +++ b/src/Cnblogs.DashScope.Core/IMaxTokenParameter.cs @@ -0,0 +1,15 @@ +namespace Cnblogs.DashScope.Core; + +/// +/// Marks parameter supports setting maximum number of output tokens. +/// +public interface IMaxTokenParameter +{ + /// + /// The maximum number of tokens the model can generate. + /// + /// + /// Default and maximum number of tokens is 1500(qwen-turbo) or 2000(qwen-max, qwen-max-1201, qwen-max-longcontext, qwen-plus). + /// + public int? MaxTokens { get; } +} diff --git a/src/Cnblogs.DashScope.Core/IMultimodalParameters.cs b/src/Cnblogs.DashScope.Core/IMultimodalParameters.cs index 42faaf7..c1a2f7f 100644 --- a/src/Cnblogs.DashScope.Core/IMultimodalParameters.cs +++ b/src/Cnblogs.DashScope.Core/IMultimodalParameters.cs @@ -3,4 +3,12 @@ /// /// Optional parameters for multi-model generation request. /// -public interface IMultimodalParameters : IProbabilityParameter, ISeedParameter, IIncrementalOutputParameter; +public interface IMultimodalParameters + : IProbabilityParameter, ISeedParameter, IIncrementalOutputParameter, IPenaltyParameter, IMaxTokenParameter, + IStopTokenParameter +{ + /// + /// Allow higher resolution for inputs. When setting to true, increases the maximum input token from 1280 to 16384. Defaults to false. + /// + public bool? VlHighResolutionImages { get; } +} diff --git a/src/Cnblogs.DashScope.Core/IPenaltyParameter.cs b/src/Cnblogs.DashScope.Core/IPenaltyParameter.cs new file mode 100644 index 0000000..d00a6e3 --- /dev/null +++ b/src/Cnblogs.DashScope.Core/IPenaltyParameter.cs @@ -0,0 +1,18 @@ +namespace Cnblogs.DashScope.Core; + +/// +/// Marks parameter accepts presence_penalty and repetition_penalty options. +/// +public interface IPenaltyParameter +{ + /// + /// Increasing the repetition penalty can reduce the amount of repetition in the model’s output. A value of 1.0 indicates no penalty, with the default set at 1.1. + /// + public float? RepetitionPenalty { get; } + + /// + /// Control the content repetition in text generated by the model. + /// + /// Must be in [-2.0, 2.0]. Use higher penalty for batter creativity. + public float? PresencePenalty { get; } +} diff --git a/src/Cnblogs.DashScope.Core/IProbabilityParameter.cs b/src/Cnblogs.DashScope.Core/IProbabilityParameter.cs index 0b9eb74..0efa681 100644 --- a/src/Cnblogs.DashScope.Core/IProbabilityParameter.cs +++ b/src/Cnblogs.DashScope.Core/IProbabilityParameter.cs @@ -1,7 +1,7 @@ namespace Cnblogs.DashScope.Core; /// -/// Marks parameter accepts top_p and top_k options. +/// Marks parameter accepts top_p, top_k and temperature options. /// public interface IProbabilityParameter { @@ -16,4 +16,10 @@ public interface IProbabilityParameter /// /// top_k would been disabled if applied null or any value larger than 100. public int? TopK { get; } + + /// + /// Controls the diversity of generations. Lower temperature leads to more consistent result. + /// + /// Must be in [0,2), qwen-max defaults to 0.7. + public float? Temperature { get; } } diff --git a/src/Cnblogs.DashScope.Core/IStopTokenParameter.cs b/src/Cnblogs.DashScope.Core/IStopTokenParameter.cs new file mode 100644 index 0000000..793f6a0 --- /dev/null +++ b/src/Cnblogs.DashScope.Core/IStopTokenParameter.cs @@ -0,0 +1,12 @@ +namespace Cnblogs.DashScope.Core; + +/// +/// Marks parameter supports setting stop tokens. +/// +public interface IStopTokenParameter +{ + /// + /// Stop generation when next token or string is in given range. + /// + public TextGenerationStop? Stop { get; } +} diff --git a/src/Cnblogs.DashScope.Core/ITextGenerationParameters.cs b/src/Cnblogs.DashScope.Core/ITextGenerationParameters.cs index 2e2072a..6466e73 100644 --- a/src/Cnblogs.DashScope.Core/ITextGenerationParameters.cs +++ b/src/Cnblogs.DashScope.Core/ITextGenerationParameters.cs @@ -3,7 +3,8 @@ /// /// The text generation options. /// -public interface ITextGenerationParameters : IIncrementalOutputParameter, ISeedParameter, IProbabilityParameter +public interface ITextGenerationParameters + : IIncrementalOutputParameter, ISeedParameter, IProbabilityParameter, IPenaltyParameter, IMaxTokenParameter, IStopTokenParameter { /// /// The format of the result message, must be text or message. @@ -14,30 +15,6 @@ public interface ITextGenerationParameters : IIncrementalOutputParameter, ISeedP /// public string? ResultFormat { get; } - /// - /// The maximum number of tokens the model can generate. - /// - /// - /// Default and maximum number of tokens is 1500(qwen-turbo) or 2000(qwen-max, qwen-max-1201, qwen-max-longcontext, qwen-plus). - /// - public int? MaxTokens { get; } - - /// - /// Increasing the repetition penalty can reduce the amount of repetition in the model’s output. A value of 1.0 indicates no penalty, with the default set at 1.1. - /// - public float? RepetitionPenalty { get; } - - /// - /// Controls the diversity of generations. Lower temperature leads to more consistent result. - /// - /// Must be in [0,2), defaults to 0.85. - public float? Temperature { get; } - - /// - /// Stop generation when next token or string is in given range. - /// - public TextGenerationStop? Stop { get; } - /// /// Enable internet search when generation. Defaults to false. /// @@ -46,5 +23,10 @@ public interface ITextGenerationParameters : IIncrementalOutputParameter, ISeedP /// /// Available tools for model to call. /// - public List? Tools { get; } + public IEnumerable? Tools { get; } + + /// + /// Behavior when choosing tools. + /// + public ToolChoice? ToolChoice { get; } } diff --git a/src/Cnblogs.DashScope.Core/MultimodalParameters.cs b/src/Cnblogs.DashScope.Core/MultimodalParameters.cs index 8a4a263..dc6b98b 100644 --- a/src/Cnblogs.DashScope.Core/MultimodalParameters.cs +++ b/src/Cnblogs.DashScope.Core/MultimodalParameters.cs @@ -11,9 +11,27 @@ public class MultimodalParameters : IMultimodalParameters /// public int? TopK { get; set; } + /// + public float? Temperature { get; set; } + /// public ulong? Seed { get; set; } /// public bool? IncrementalOutput { get; set; } + + /// + public bool? VlHighResolutionImages { get; set; } + + /// + public float? RepetitionPenalty { get; set; } + + /// + public float? PresencePenalty { get; set; } + + /// + public int? MaxTokens { get; set; } + + /// + public TextGenerationStop? Stop { get; set; } } diff --git a/src/Cnblogs.DashScope.Core/TextGenerationParameters.cs b/src/Cnblogs.DashScope.Core/TextGenerationParameters.cs index e4308f6..fbe42e5 100644 --- a/src/Cnblogs.DashScope.Core/TextGenerationParameters.cs +++ b/src/Cnblogs.DashScope.Core/TextGenerationParameters.cs @@ -23,6 +23,9 @@ public class TextGenerationParameters : ITextGenerationParameters /// public float? RepetitionPenalty { get; set; } + /// + public float? PresencePenalty { get; set; } + /// public float? Temperature { get; set; } @@ -33,7 +36,10 @@ public class TextGenerationParameters : ITextGenerationParameters public bool? EnableSearch { get; set; } /// - public List? Tools { get; set; } + public IEnumerable? Tools { get; set; } + + /// + public ToolChoice? ToolChoice { get; set; } /// public bool? IncrementalOutput { get; set; } diff --git a/src/Cnblogs.DashScope.Core/ToolChoice.cs b/src/Cnblogs.DashScope.Core/ToolChoice.cs new file mode 100644 index 0000000..030c5c4 --- /dev/null +++ b/src/Cnblogs.DashScope.Core/ToolChoice.cs @@ -0,0 +1,47 @@ +using System.Text.Json.Serialization; + +namespace Cnblogs.DashScope.Core; + +/// +/// Specify the behavior for model when tools are applied. +/// +[JsonConverter(typeof(ToolChoiceJsonConverter))] +public record ToolChoice +{ + /// + /// Make sure tool choices can not be initiated directly. + /// + private ToolChoice(string type, ToolChoiceFunction? function = null) + { + Type = type; + Function = function; + } + + /// + /// The type of tool choice. + /// + public string Type { get; } + + /// + /// The function that model must call. + /// + public ToolChoiceFunction? Function { get; } + + /// + /// Model can not call any tools. + /// + public static readonly ToolChoice NoneChoice = new("none"); + + /// + /// Model can freely pick between generating a message or calling one or more tools. + /// + public static readonly ToolChoice AutoChoice = new("auto"); + + /// + /// Model must call function with specified name. + /// + /// Name of function. + /// + public static ToolChoice FunctionChoice(string functionName) + => new("function", new ToolChoiceFunction(functionName)); +} diff --git a/src/Cnblogs.DashScope.Core/ToolChoiceFunction.cs b/src/Cnblogs.DashScope.Core/ToolChoiceFunction.cs new file mode 100644 index 0000000..3e0c856 --- /dev/null +++ b/src/Cnblogs.DashScope.Core/ToolChoiceFunction.cs @@ -0,0 +1,7 @@ +namespace Cnblogs.DashScope.Core; + +/// +/// Represents functions that model must call. +/// +/// The name of the function. +public record ToolChoiceFunction(string Name); diff --git a/src/Cnblogs.DashScope.Core/ToolChoiceJsonConverter.cs b/src/Cnblogs.DashScope.Core/ToolChoiceJsonConverter.cs new file mode 100644 index 0000000..14cfefe --- /dev/null +++ b/src/Cnblogs.DashScope.Core/ToolChoiceJsonConverter.cs @@ -0,0 +1,69 @@ +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace Cnblogs.DashScope.Core; + +/// +/// The converter for +/// +public class ToolChoiceJsonConverter : JsonConverter +{ + /// + public override ToolChoice? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + { + if (reader.TokenType == JsonTokenType.String) + { + var str = reader.GetString(); + return str switch + { + "auto" => ToolChoice.AutoChoice, + "none" => ToolChoice.NoneChoice, + _ => throw new JsonException("Unknown tool choice type") + }; + } + + if (reader.TokenType == JsonTokenType.Null) + { + return null; + } + + if (reader.TokenType != JsonTokenType.StartObject) + { + throw new JsonException("Unknown tool choice."); + } + + var element = JsonSerializer.Deserialize(ref reader, options); + var functionValid = element.TryGetProperty("function", out var function); + var typeValid = element.TryGetProperty("type", out var type); + if (functionValid == false || typeValid == false || type.ValueKind != JsonValueKind.String) + { + throw new JsonException("Unknown tool choice type"); + } + + var toolFunction = function.Deserialize(options); + var toolChoiceType = type.GetString(); + if (toolFunction == null || toolChoiceType != "function") + { + throw new JsonException("Unknown tool choice type"); + } + + return ToolChoice.FunctionChoice(toolFunction.Name); + } + + /// + public override void Write(Utf8JsonWriter writer, ToolChoice value, JsonSerializerOptions options) + { + if (value.Type != "function") + { + writer.WriteStringValue(value.Type); + } + else + { + writer.WriteStartObject(); + writer.WriteString("type", value.Type); + writer.WritePropertyName("function"); + JsonSerializer.Serialize(writer, value.Function, options); + writer.WriteEndObject(); + } + } +} diff --git a/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/multimodal-generation-vl-nosse.request.body.json b/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/multimodal-generation-vl-nosse.request.body.json index 6034d14..0b0bb59 100644 --- a/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/multimodal-generation-vl-nosse.request.body.json +++ b/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/multimodal-generation-vl-nosse.request.body.json @@ -20,6 +20,12 @@ "parameters": { "seed": 1234, "top_k": 100, - "top_p": 0.81 + "top_p": 0.81, + "vl_high_resolution_images": true, + "temperature": 1.1, + "repetition_penalty": 1.3, + "presence_penalty": 1.2, + "max_tokens": 120, + "stop": "你好" } } diff --git a/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/multimodal-generation-vl-nosse.response.body.txt b/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/multimodal-generation-vl-nosse.response.body.txt index 4ecdb8f..1a206a5 100644 --- a/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/multimodal-generation-vl-nosse.response.body.txt +++ b/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/multimodal-generation-vl-nosse.response.body.txt @@ -1 +1 @@ -{"output":{"choices":[{"finish_reason":"stop","message":{"role":"assistant","content":[{"text":"这张照片显示的是海滩景色,但是无法确定具体的位置信息。图中有一名女子和一只狗在沙滩上互动。背景中有海洋和日出或日落的光线。由于缺乏特定地标或者细节特征,仅凭此图像很难精确识别具体的地点。"}]}}]},"usage":{"output_tokens":58,"input_tokens":1284,"image_tokens":1247},"request_id":"a2a5f2e6-c6d7-9e04-9f92-1d3eee274198"} +{"output":{"choices":[{"finish_reason":"stop","message":{"role":"assistant","content":[{"text":"这是在海滩上。"}]}}]},"usage":{"output_tokens":6,"input_tokens":3613,"image_tokens":3577},"request_id":"e74b364a-034f-9d0d-8e55-8e5b3580045f"} \ No newline at end of file diff --git a/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/multimodal-generation-vl-nosse.response.header.txt b/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/multimodal-generation-vl-nosse.response.header.txt index f0a0026..46cc64f 100644 --- a/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/multimodal-generation-vl-nosse.response.header.txt +++ b/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/multimodal-generation-vl-nosse.response.header.txt @@ -1,13 +1,15 @@ -HTTP/1.1 200 OK -eagleeye-traceid: cf6954f685a19435530858304250b3bc -content-type: application/json +HTTP/1.1 200 OK +eagleeye-traceid: c72728928fd0d00883f6edd204cc6721 +Vary: Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Accept-Encoding +X-Request-ID: e74b364a-034f-9d0d-8e55-8e5b3580045f +x-dashscope-timeout: 180 x-dashscope-call-gateway: true -req-cost-time: 4359 -req-arrive-time: 1709019927268 -resp-start-time: 1709019931627 -x-envoy-upstream-service-time: 4353 -content-encoding: gzip -vary: Accept-Encoding -date: Tue, 27 Feb 2024 07:45:31 GMT -server: istio-envoy -transfer-encoding: chunked +x-dashscope-finished: true +req-cost-time: 3064 +req-arrive-time: 1732531979928 +resp-start-time: 1732531982993 +x-envoy-upstream-service-time: 3054 +Set-Cookie: acw_tc=e74b364a-034f-9d0d-8e55-8e5b3580045f47b5c24e3af603d8590358e45e4696a6;path=/;HttpOnly;Max-Age=1800 +Date: Mon, 25 Nov 2024 10:53:02 GMT +Server: istio-envoy +Transfer-Encoding: chunked diff --git a/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/single-generation-message-with-tools-nosse.request.body.json b/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/single-generation-message-with-tools-nosse.request.body.json index 74addce..67f0342 100644 --- a/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/single-generation-message-with-tools-nosse.request.body.json +++ b/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/single-generation-message-with-tools-nosse.request.body.json @@ -15,8 +15,9 @@ "top_p": 0.8, "top_k": 100, "repetition_penalty": 1.1, + "presence_penalty": 1.2, "temperature": 0.85, - "stop": [[37763, 367]], + "stop": "你好", "enable_search": false, "incremental_output": false, "tools": [ @@ -46,6 +47,12 @@ } } } - ] + ], + "tool_choice": { + "type": "function", + "function": { + "name": "get_current_weather" + } + } } } diff --git a/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/single-generation-message-with-tools-nosse.response.body.txt b/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/single-generation-message-with-tools-nosse.response.body.txt index c1f1ae6..cb75b47 100644 --- a/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/single-generation-message-with-tools-nosse.response.body.txt +++ b/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/single-generation-message-with-tools-nosse.response.body.txt @@ -1 +1 @@ -{"output":{"choices":[{"finish_reason":"tool_calls","message":{"role":"assistant","tool_calls":[{"function":{"name":"get_current_weather","arguments":"{\"location\": \"浙江省杭州市\", \"unit\": \"Celsius\"}"},"id":"","type":"function"}],"content":""}}]},"usage":{"total_tokens":36,"output_tokens":31,"input_tokens":5},"request_id":"40b4361e-e936-91b5-879d-355a45d670f8"} +{"output":{"choices":[{"finish_reason":"stop","message":{"role":"assistant","tool_calls":[{"function":{"name":"get_current_weather","arguments":"{\"location\": \"浙江省杭州市\"}"},"index":0,"id":"call_cec4c19d27624537b583af","type":"function"}],"content":""}}]},"usage":{"total_tokens":219,"output_tokens":8,"input_tokens":211},"request_id":"67300049-c108-9987-b1c1-8e0ee2de6b5d"} \ No newline at end of file diff --git a/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/single-generation-message-with-tools-nosse.response.header.txt b/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/single-generation-message-with-tools-nosse.response.header.txt index 62317c7..111c929 100644 --- a/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/single-generation-message-with-tools-nosse.response.header.txt +++ b/test/Cnblogs.DashScope.Sdk.UnitTests/RawHttpData/single-generation-message-with-tools-nosse.response.header.txt @@ -1,14 +1,14 @@ -HTTP/1.1 200 OK -eagleeye-traceid: 7328e5207abf69133abfe3a68446fc2d -content-type: application/json +HTTP/1.1 200 OK +eagleeye-traceid: 4c11425c43fe6d3cd142b49fa668a3f8 +Vary: Origin,Access-Control-Request-Method,Access-Control-Request-Headers,Accept-Encoding +X-Request-ID: 67300049-c108-9987-b1c1-8e0ee2de6b5d +x-dashscope-timeout: 180 x-dashscope-call-gateway: true -x-dashscope-experiments: 33e6d810-qwen-max-base-default-imbalance-fix-lua -req-cost-time: 3898 -req-arrive-time: 1710324737299 -resp-start-time: 1710324741198 -x-envoy-upstream-service-time: 3893 -content-encoding: gzip -vary: Accept-Encoding -date: Wed, 13 Mar 2024 10:12:21 GMT -server: istio-envoy -transfer-encoding: chunked +x-dashscope-finished: true +req-cost-time: 1050 +req-arrive-time: 1732528382029 +resp-start-time: 1732528383079 +x-envoy-upstream-service-time: 1042 +Date: Mon, 25 Nov 2024 09:53:03 GMT +Server: istio-envoy +Transfer-Encoding: chunked diff --git a/test/Cnblogs.DashScope.Sdk.UnitTests/ToolChoiceJsonConverterTests.cs b/test/Cnblogs.DashScope.Sdk.UnitTests/ToolChoiceJsonConverterTests.cs new file mode 100644 index 0000000..077a4b0 --- /dev/null +++ b/test/Cnblogs.DashScope.Sdk.UnitTests/ToolChoiceJsonConverterTests.cs @@ -0,0 +1,68 @@ +using System.Text.Json; +using Cnblogs.DashScope.Core; +using FluentAssertions; + +namespace Cnblogs.DashScope.Sdk.UnitTests; + +public class ToolChoiceJsonConverterTests +{ + private static readonly JsonSerializerOptions SerializerOptions = + new() { PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower }; + + [Theory] + [MemberData(nameof(Data))] + public void TextGenerationStopConvertor_Serialize_Success(ToolChoice? choice, string json) + { + // Arrange + var obj = new TestObj(choice); + + // Act + var actual = JsonSerializer.Serialize(obj, SerializerOptions); + + // Assert + actual.Should().Be(json); + } + + [Theory] + [MemberData(nameof(Data))] + public void TextGenerationStopConvertor_Deserialize_Success(ToolChoice? choice, string json) + { + // Act + var obj = JsonSerializer.Deserialize(json, SerializerOptions); + + // Assert + obj.Should().BeEquivalentTo(new TestObj(choice)); + } + + [Theory] + [MemberData(nameof(InvalidJson))] + public void TextGenerationStopConvertor_InvalidJson_Exception(string json) + { + // Act + var act = () => JsonSerializer.Deserialize(json, SerializerOptions); + + // Assert + act.Should().Throw(); + } + + public record TestObj(ToolChoice? Choice); + + public static TheoryData Data + => new() + { + { ToolChoice.AutoChoice, """{"choice":"auto"}""" }, + { ToolChoice.NoneChoice, """{"choice":"none"}""" }, + { ToolChoice.FunctionChoice("weather"), """{"choice":{"type":"function","function":{"name":"weather"}}}""" }, + { null, """{"choice":null}""" } + }; + + public static TheoryData InvalidJson + => new() + { + """{"choice":{}}""", + """{"choice":"other"}""", + """{"choice":{"type":"other"}}""", + """{"choice":{"type":"other", "function":{"name": "weather"}}}""", + """{"choice":{"type":"function", "function": "other"}}""" + }; +} diff --git a/test/Cnblogs.DashScope.Sdk.UnitTests/Utils/Snapshots.cs b/test/Cnblogs.DashScope.Sdk.UnitTests/Utils/Snapshots.cs index 89d0e5c..ec6cf77 100644 --- a/test/Cnblogs.DashScope.Sdk.UnitTests/Utils/Snapshots.cs +++ b/test/Cnblogs.DashScope.Sdk.UnitTests/Utils/Snapshots.cs @@ -297,8 +297,9 @@ public static readonly TopP = 0.8f, TopK = 100, RepetitionPenalty = 1.1f, + PresencePenalty = 1.2f, Temperature = 0.85f, - Stop = new([[37763, 367]]), + Stop = new("你好"), EnableSearch = false, IncrementalOutput = false, Tools = @@ -314,7 +315,8 @@ public static readonly PropertyNameResolver = PropertyNameResolvers.LowerSnakeCase }) .Build())) - ] + ], + ToolChoice = ToolChoice.FunctionChoice("get_current_weather") } }, new() @@ -325,28 +327,28 @@ public static readonly [ new() { - FinishReason = "tool_calls", + FinishReason = "stop", Message = new( "assistant", string.Empty, ToolCalls: [ - new( - string.Empty, + new ToolCall( + "call_cec4c19d27624537b583af", ToolTypes.Function, new FunctionCall( "get_current_weather", - """{"location": "浙江省杭州市", "unit": "Celsius"}""")) + """{"location": "浙江省杭州市"}""")) ]) } ] }, - RequestId = "40b4361e-e936-91b5-879d-355a45d670f8", + RequestId = "67300049-c108-9987-b1c1-8e0ee2de6b5d", Usage = new() { - InputTokens = 5, - OutputTokens = 31, - TotalTokens = 36 + InputTokens = 211, + OutputTokens = 8, + TotalTokens = 219 } }); @@ -483,7 +485,13 @@ public static class MultimodalGeneration { Seed = 1234, TopK = 100, - TopP = 0.81f + TopP = 0.81f, + Temperature = 1.1f, + VlHighResolutionImages = true, + RepetitionPenalty = 1.3f, + PresencePenalty = 1.2f, + MaxTokens = 120, + Stop = "你好" } }, new() @@ -497,15 +505,15 @@ public static class MultimodalGeneration [ new( null, - "这张照片显示的是海滩景色,但是无法确定具体的位置信息。图中有一名女子和一只狗在沙滩上互动。背景中有海洋和日出或日落的光线。由于缺乏特定地标或者细节特征,仅凭此图像很难精确识别具体的地点。") + "这是在海滩上。") ])) ]), - RequestId = "a2a5f2e6-c6d7-9e04-9f92-1d3eee274198", + RequestId = "e74b364a-034f-9d0d-8e55-8e5b3580045f", Usage = new() { - OutputTokens = 58, - InputTokens = 1284, - ImageTokens = 1247 + OutputTokens = 6, + InputTokens = 3613, + ImageTokens = 3577 } });