Java学习之-SpringAI

news2024/12/29 16:12:24

文章目录

  • 一、SpringAI是什么
  • 二、准备工作
    • 1.GPT-API-free
    • 2.AiCore
    • 3.eylink
  • 三、对话案例实现
    • 1.创建项目
    • 2.实现简单的对话
  • 四、聊天客户端ChatClient
    • 1.角色预设
    • 2.流式响应
  • 五、聊天模型
  • 六、图像模型(文生图)
  • 七、语音模型
    • 1.文字转语音(文生语音)
    • 2.语音转文字
  • 八、多模态
  • 九、函数调用


一、SpringAI是什么

SpringAI是一个AI工程应用框架,旨在将Spring生态系统的设计原则(如可移植性和模块化设计)应用于AI领域。它推广使用Plain Old Java Object(POJO)作为AI应用程序的构建块,从而为Java开发者提供了一种更简洁的方式与人工智能进行交互。SpringAI的推出被认为是Java开发领域的一大福音,因为它结合了Spring生态系统的设计原则和模块化的概念,降低了接入大型语言模型(LLM)的学习成本。SpringInitializr是SpringAI上架的平台,使得Java开发者能够利用SpringAI构建自己的应用程序。

简单而言,Spring AI 是AI工程师所使用的一种应用性框架,通过提供出来的API和API key来进行开发应用,所用在于使用AI应用来简化开发工序流程。

名称地址
SpringAI官网https://spring.io/projects/spring-ai
SpringAI API官网https://docs.spring.io/spring-ai/reference/api/chatclient.html

二、准备工作

我们需要准备OpenAI的key秘钥和API地址。以下是我整理的获取途径:

1.GPT-API-free

访问:https://gitcode.com/chatanywhere/GPT_API_free/overview

点击申请内测免费Key

在这里插入图片描述

  • 免费版支持gpt-3.5-turbo, embedding,gpt-4。其中gpt-4由于价格过高,每天限制3次调用(0点刷新)。需要更稳定快速的gpt-4请使用付费版。
  • 免费版gpt-4由gpt-4o提供服务,支持识图等付费版API全部功能。
  • 转发Host1:https://api.chatanywhere.tech (国内中转,延时更低,host1和host2二选一)
  • 转发Host2:https://api.chatanywhere.com.cn (国内中转,延时更低,host1和host2二选一)
  • 转发Host3:https://api.chatanywhere.cn (国外使用,国内需要全局代理)

2.AiCore

访问地址:https://api.xty.app
注册登录后可以创建令牌
注意:不是纯免费
接口地址/BaseURL/密钥地址/代理地址(不同软件配置方式不同,请用下面的地址逐一测试):
https://api.xty.app,备用加速地址: https://hk.xty.app
https://api.xty.app/v1,备用加速地址: https://hk.xty.app/v1

淘宝搜: open ai key也可以直接购买

3.eylink

访问地址:https://eylink.cn/

三、对话案例实现

版本依赖:JDK17+SpringBoot3.3+SpringAI1.0.0-M1

1.创建项目

使用IDEA创建Springboot项目,一定要使用JDK17,看其他博主说的非17会出现版本错误(本人未测试)。
在这里插入图片描述

这里我们选择Maven,JDK和Java版本选择17.
在这里插入图片描述

在这里插入图片描述
按照自己需求引入依赖。Spring Web和OpenAI为必须引入

pom文件依赖如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.cheryl</groupId>
    <artifactId>springai-learn</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springai-learn</name>
    <description>springai-learn</description>
    <properties>
        <java.version>17</java.version>
        <spring-ai.version>1.0.0-M1</spring-ai.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.ai</groupId>
                <artifactId>spring-ai-bom</artifactId>
                <version>${spring-ai.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

</project>

更改配置文件:

spring:
  application:
    name: Spring-Ai-Demo
  ai:
    openai:
      api-key: sk-XdZSQDaRxxxxxx #此次是获取的API-key
      base-url: https://apixxxxxxxxx.tech # 这里是请求代理地址

如果想直接访问OpenAI不想使用以上配置的代理地址,则需要在代码中进行配置代理,代码如下:

@SpringBootApplication
public class SpringaiLearnApplication {

    public static void main(String[] args) {
        // 设置代理
        String proxy = "127.0.0.1";  // 如果代理在你本机就127.0.0.1如果代理是其他服务器相应设置
        int port = 7890;   //设置科学上网代理的端口,
        System.setProperty("proxyType", "4");
        System.setProperty("proxyPort", Integer.toString(port));
        System.setProperty("proxyHost", proxy);
        System.setProperty("proxySet", "true");
        SpringApplication.run(SpringaiLearnApplication.class, args);
    }
}

2.实现简单的对话

新建AIController,实现下列代码:

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/ai")
class AIController {

    private final ChatClient chatClient;

    public AIController(ChatClient.Builder chatClientBuilder) {
        this.chatClient = chatClientBuilder.build();
    }

    @GetMapping("/chat")
    public String chat(@RequestParam(value = "msg",defaultValue = "给我讲个笑话") String message) {
        //prompt:提示词
        return this.chatClient.prompt()
                //用户输入的信息
                .user(message)
                //请求大模型
                .call()
                //返回文本
                .content();
    }
}

调用结果如下:
在这里插入图片描述
在这个简单示例中,用户输入设置用户消息的内容。 call 方法向 AI 模型发送请求,context 方法以 String 形式返回 AI 模型的响应。

四、聊天客户端ChatClient

ChatClient提供了一个流畅的 API,用于与 AI 模型进行通信。 它支持同步编程模型和响应式编程模型。

1.角色预设

创建AIConfig文件配置默认角色

@Configuration
public class AIConfig {

    @Bean
    public ChatClient chatClient(ChatClient.Builder builder) {
        return builder.defaultSystem("你是考拉教育的一名老师,你精通Java开发,你的名字叫考拉AI。").build();
    }
}

修改controller如下:

@RestController
@RequestMapping("/ai")
@RequiredArgsConstructor
class AIController {

    private final ChatClient chatClient;

    @GetMapping("/chat")
    public String chat(@RequestParam(value = "msg") String message) {
        return chatClient.prompt().user(message).call().content();
    }
}

请求结果如下:
在这里插入图片描述

2.流式响应

注意要配置编码格式

    @GetMapping(value = "/chat/stream",produces="text/html;charset=UTF-8")
    public Flux<String> chatStream(@RequestParam(value = "msg") String message) {
        return chatClient.prompt().user(message).stream().content();
    }

在这里插入图片描述

五、聊天模型

聊天模型 API 使开发人员能够将 AI 驱动的聊天完成功能集成到他们的应用程序中。它利用预训练的语言模型,如GPT(生成式预训练转换器),以自然语言生成类似人类的用户输入响应。

API 通常通过向 AI 模型发送提示或部分对话来工作,然后 AI 模型根据其训练数据和对自然语言模式的理解生成对话的完成或延续。然后,完成的响应将返回给应用程序,应用程序可以将其呈现给用户或将其用于进一步处理。

它被设计成一个简单且可移植的界面,用于与各种 AI 模型进行交互,允许开发人员以最少的代码更改在不同模型之间切换。 这种设计符合Spring的模块化和可互换性理念。Spring AI Chat Model API

此外,在输入封装和输出处理等配套类的帮助下,聊天模型 API 统一了与 AI 模型的通信。 它管理请求准备和响应解析的复杂性,提供直接和简化的 API 交互。PromptChatResponse

本文只展示使用OpenAI的方式,更多方式请查看官方文档

Spring AI 支持 OpenAI 的 AI 语言模型 ChatGPT。ChatGPT 在激发人们对 AI 驱动的文本生成的兴趣方面发挥了重要作用,这要归功于它创建了行业领先的文本生成模型和嵌入。

官网地址:https://docs.spring.io/spring-ai/reference/api/chat/openai-chat.html

package com.cheryl.springailearn.controller;

import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.messages.Media;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.ai.openai.api.OpenAiApi;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.MimeTypeUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

import java.io.IOException;
import java.net.URL;
import java.util.List;

@RequestMapping("/chat/model")
@RequiredArgsConstructor
@RestController
public class ChatModelController {
    private final ChatModel chatModel;

    @GetMapping
    public String chat(@RequestParam("msg")String msg) {
        return chatModel.call(msg);
    }

    /**
     * Spring AI 支持 OpenAI 的 AI 语言模型 ChatGPT
     * @param msg
     * @return
     */
    @GetMapping("/openai")
    public String openai(@RequestParam("msg")String msg) {
        ChatResponse call = chatModel.call(
                new Prompt(
                        msg,
                        OpenAiChatOptions.builder()//可以更换成其他大模型,如Anthropic3ChatOptions亚马逊
                                .withModel("gpt-3.5-turbo")
                                .withTemperature(0.8F)
                                .build()
                )
        );
        return call.getResult().getOutput().getContent();
    }
    /**
     * 流式响应
     * @param msg
     * @return
     */
    @GetMapping(value = "/openai/stream",produces="text/html;charset=UTF-8")
    public Flux<ChatResponse> stream(@RequestParam("msg")String msg) {
        return chatModel.stream(
                new Prompt(
                        msg,
                        OpenAiChatOptions.builder()//可以更换成其他大模型,如Anthropic3ChatOptions亚马逊
                                .withModel("gpt-3.5-turbo")
                                .withTemperature(0.8F)
                                .build()
                )
        );
    }
}

六、图像模型(文生图)

属性配置官网:https://docs.spring.io/spring-ai/reference/api/image/openai-image.html

import lombok.RequiredArgsConstructor;
import org.springframework.ai.image.ImagePrompt;
import org.springframework.ai.image.ImageResponse;
import org.springframework.ai.openai.OpenAiImageModel;
import org.springframework.ai.openai.OpenAiImageOptions;
import org.springframework.ai.openai.api.OpenAiImageApi;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/image")
@RestController
@RequiredArgsConstructor
public class ImageModelController {

    private final OpenAiImageModel openaiImageModel;

    @GetMapping
    public String getImage(@RequestParam(value = "msg",defaultValue = "生成一直小猫")String msg) {
        ImageResponse response = openaiImageModel.call(
                new ImagePrompt(
                        msg,
                        OpenAiImageOptions.builder()
                                .withQuality("hd")//将生成的图像的质量。HD 创建的图像具有更精细的细节和更高的图像一致性。只有 dall-e-3 支持此参数。
                                .withModel(OpenAiImageApi.DEFAULT_IMAGE_MODEL)
                                .withN(1)//要生成的图像数。必须介于 1 和 10 之间。对于 dall-e-3,仅支持 n=1。
                                .withHeight(1024)//生成的图像的高宽度。必须是 dall-e-2 的 256、512 或 1024 之一。
                                .withWidth(1024).build())
        );
        return response.getResult().getOutput().getUrl();
    }

}

七、语音模型

1.文字转语音(文生语音)

import lombok.RequiredArgsConstructor;
import org.springframework.ai.openai.OpenAiAudioSpeechModel;
import org.springframework.ai.openai.OpenAiAudioSpeechOptions;
import org.springframework.ai.openai.api.OpenAiAudioApi;
import org.springframework.ai.openai.audio.speech.SpeechPrompt;
import org.springframework.ai.openai.audio.speech.SpeechResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.FileOutputStream;
import java.io.IOException;

@RequestMapping("/audio")
@RequiredArgsConstructor
@RestController
public class AudioModelController {

    private final OpenAiAudioSpeechModel openAiAudioSpeechModel;

    @GetMapping
    public void text2audio() throws IOException {
        OpenAiAudioSpeechOptions speechOptions = OpenAiAudioSpeechOptions.builder()
                .withModel("tts-1")//要使用的模型的 ID。目前只有 tts-1 可用。
                .withVoice(OpenAiAudioApi.SpeechRequest.Voice.ALLOY)//用于 TTS 输出的语音。可用选项包括:alloy, echo, fable, onyx, nova, and shimmer.
                .withResponseFormat(OpenAiAudioApi.SpeechRequest.AudioResponseFormat.MP3)//音频输出的格式。支持的格式包括 mp3、opus、aac、flac、wav 和 pcm。
                .withSpeed(1.0f)//语音合成的速度。可接受的范围是从 0.0(最慢)到 1.0(最快)
                .build();

        //要转换的语音内容
        SpeechPrompt speechPrompt = new SpeechPrompt("你好,这是一个文本到语音的例子。", speechOptions);
        SpeechResponse response = openAiAudioSpeechModel.call(speechPrompt);
        byte[] output = response.getResult().getOutput();
        //将文件输出到指定位置
        writeByteArrayToMp3(output,"/Users/mac/Desktop/project/java");
    }

    public static void writeByteArrayToMp3(byte[] audioBytes, String outputFilePath) throws IOException {
        // 创建FileOutputStream实例
        FileOutputStream fos = new FileOutputStream(outputFilePath+"/audio_demo.mp3");

        // 将字节数组写入文件
        fos.write(audioBytes);

        // 关闭文件输出流
        fos.close();
    }
}

2.语音转文字

import lombok.RequiredArgsConstructor;
import org.springframework.ai.openai.OpenAiAudioTranscriptionModel;
import org.springframework.ai.openai.OpenAiAudioTranscriptionOptions;
import org.springframework.ai.openai.api.OpenAiAudioApi;
import org.springframework.ai.openai.audio.transcription.AudioTranscriptionPrompt;
import org.springframework.ai.openai.audio.transcription.AudioTranscriptionResponse;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RequestMapping("/audio")
@RequiredArgsConstructor
@RestController
public class AudioModelController {

    private final OpenAiAudioTranscriptionModel openAiTranscriptionModel;

    @GetMapping("/audio2text")
    public String audio2text(){
        //脚本输出的格式,位于以下选项之一中:json、text、srt、verbose_json 或 vtt。
        OpenAiAudioApi.TranscriptResponseFormat responseFormat = OpenAiAudioApi.TranscriptResponseFormat.TEXT;

        OpenAiAudioTranscriptionOptions transcriptionOptions = OpenAiAudioTranscriptionOptions.builder()
                .withLanguage("en")//输入音频的语言。以 ISO-639-1 格式提供输入语言将提高准确性和延迟。
                .withPrompt("Ask not this, but ask that")//用于指导模型样式或继续上一个音频片段的可选文本。提示应与音频语言匹配。
                .withTemperature(0f)//采样温度,介于 0 和 1 之间。较高的值(如 0.8)将使输出更具随机性,而较低的值(如 0.2)将使其更加集中和确定。如果设置为 0,模型将使用对数概率自动提高温度,直到达到某些阈值。
                .withResponseFormat(responseFormat)//输出格式
                .build();
        //获取当前语音文件
        ClassPathResource audioFile = new ClassPathResource("audio_demo.mp3");
        AudioTranscriptionPrompt transcriptionRequest = new AudioTranscriptionPrompt(audioFile, transcriptionOptions);
        AudioTranscriptionResponse response = openAiTranscriptionModel.call(transcriptionRequest);
        return response.getResult().getOutput();
    }
}

八、多模态

多模态是指模型同时理解和处理来自各种来源的信息的能力,包括文本、图像、音频和其他数据格式。

	/**
     * 多模态是指模型同时理解和处理来自各种来源的信息的能力,包括文本、图像、音频和其他数据格式。 
     * 仅支持 chatGPT4.0
     * @param msg
     * @return
     */
    @GetMapping(value = "/openai/multimodal",produces="text/html;charset=UTF-8")
    public String multimodal(@RequestParam("msg")String msg) throws IOException {
        byte[] imageData = new ClassPathResource("/multimodal.test.png").getContentAsByteArray();
        var userMessage = new UserMessage(msg,
                List.of(new Media(
                        MimeTypeUtils.IMAGE_PNG,
                        new URL("https://docs.spring.io/spring-ai/reference/1.0-SNAPSHOT/_images/multimodal.test.png")
                )));

        ChatResponse response = chatModel.call(new Prompt(List.of(userMessage),
                OpenAiChatOptions.builder().withModel(OpenAiApi.ChatModel.GPT_4_O.getValue()).build()));

        return response.getResult().getOutput().getContent();
    }

九、函数调用

我们创建一个聊天机器人,通过调用我们自己的函数来回答问题。 为了支持聊天机器人的响应,我们将注册我们自己的函数,该函数获取一个位置并返回该位置的当前天气。
(注意本人亲测函数调用只能在gtp4.0以上使用,注意上边说的免费版Key无法使用)
大致流程如下:
在这里插入图片描述

创建functions包,创建LocationWeatherFunction实现Function接口

package com.cheryl.springailearn.functions;

import java.util.function.Function;

public class LocationWeatherFunction implements Function <LocationWeatherFunction.Request, LocationWeatherFunction.Response>{

    // 实现apply方法
    @Override
    public Response apply(Request request) {
        System.out.println(request);
        if(request==null){
            return new Response("request is null");
        }
        if(request.location==null){
            return new Response("地址是空的");
        }
        return new Response("天气一会下雨一会晴天" );
    }

    public record Request(String location){

    }
    public record Response(String msg) {
    }
}

将函数注册为 Bean

@Description是可选的,它提供了函数描述 ,可帮助模型了解何时调用函数。这是一个重要的属性,可帮助 AI 模型确定要调用的客户端函数。

package com.cheryl.springailearn.config;

import com.cheryl.springailearn.functions.LocationWeatherFunction;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Description;

import java.util.function.Function;

@Configuration
public class AIConfig {
    @Bean
    @Description("某某地方天气怎么样")
    public Function<LocationWeatherFunction.Request, LocationWeatherFunction.Response> locationWeatherFunction(){
        return new LocationWeatherFunction();
    }
}

在聊天模型中调用函数

package com.cheryl.springailearn.controller;


import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RequestMapping("/function")
@RequiredArgsConstructor
@RestController
public class AIFunctionController {

    private final ChatModel chatModel;

    @GetMapping
    public String testFunction(){
        UserMessage userMessage = new UserMessage("济南天气怎么样?");
        OpenAiChatOptions options = OpenAiChatOptions.builder()
                .withFunction("locationWeatherFunction")
                .withModel("gpt-4-turbo")
                .build();
        ChatResponse call = chatModel.call(
                new Prompt(
                        List.of(userMessage),
                        options
                )
        );
        return call.getResult().getOutput().getContent();
    }

}

结果如下:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1818405.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Kubernetes架构详解

Kubernetes架构详解 KubernetsKubernetes架构Kubernetes主节点组件Kubernetes工作节点组件 Kubernetes是云原生非常核心的组件&#xff0c;是云计算的未来&#xff0c;也是大厂经常考察的内容&#xff0c;下面我们就全面来讲解Kubernetes架构 Kubernets Kubernets是Google开发…

超简单理解上拉电阻(高中物理)

上拉电阻的作用 一、增强电路驱动能力二、将不确定的信号钳位在高电平 一、增强电路驱动能力 单片机一个引脚输出5V 当接了一个100Ω电阻之后电压变小 此时接上一个上拉电阻&#xff0c;电压又变高了&#xff0c;提升了电路的驱动能力&#xff0c;本来是并联分压&#xff1…

17.路由配置与页面创建

路由配置与页面创建 官网&#xff1a;https://router.vuejs.org/zh/ Vue Router 和 组合式 API | Vue Router (vuejs.org) 1. 修改index.ts import { RouteRecordRaw, createRouter, createWebHistory } from "vue-router"; import Layout from /layout/Index.vueco…

【数组】【双指针】【练习】最接近的三数之和+四数之和

这篇博客主要是对上篇【数组】【双指针】三数之和做一个练习&#xff0c;包括俩相似题目&#xff1a;最接近的三数之和、四数之和 最接近的三数之和 该题对应力扣地址 有了前车之鉴&#xff0c;直接用双指针写的&#xff0c;没看题解&#xff0c;题解可能有更优化的方法&#…

Spring AI 接入OpenAI实现文字生成图片功能

Spring AI 框架集成的图片大模型 2022年出现的三款文生图的现象级产品&#xff0c;DALL-E、Stable Diffusion、Midjourney。 OpenAI dall-e-3dall-e-2 Auzre OpenAI dall-e-3dall-e-2 Stability stable-diffusion-v1-6 ZhiPuAI cogview-3 OpenAI 与 Auzer OpenAI 使用的图片…

商务风格可视化插图怎么绘制?一行代码搞定~~

上期推文推出使用极少代码绘制顶级期刊要求的学术图表(一行代码绘制符合)后&#xff0c;有小伙伴就问了&#xff0c;有没有可以使用较少代码绘制偏商业风的技巧分享&#xff1f;还别说&#xff0c;我还真有这样的技巧准备分享给爱学习的你们&#xff01;话不多说&#xff0c;咱…

基于MATLAB仿真的BCC卷积码维特比译码算法

&#x1f9d1;&#x1f3fb;个人简介&#xff1a;具有3年工作经验&#xff0c;擅长通信算法的MATLAB仿真和FPGA实现。代码事宜&#xff0c;私信博主&#xff0c;程序定制、设计指导。 &#x1f680;基于MATLAB仿真的BCC卷积码维特比译码算法 目录 &#x1f680;1.BCC卷积码概…

182.二叉树:二叉搜索树的最小绝对差(力扣)

代码解决 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* Tre…

【代码随想录】【算法训练营】【第30天 1】 [322]重新安排行程 [51]N皇后

前言 思路及算法思维&#xff0c;指路 代码随想录。 题目来自 LeetCode。 day 30&#xff0c;周四&#xff0c;好难&#xff0c;会不了一点~ 题目详情 [322] 重新安排行程 题目描述 322 重新安排行程 解题思路 前提&#xff1a;…… 思路&#xff1a;回溯。 重点&…

transformer和Non-local

两者本质上是一个东西&#xff0c;都是用来求自注意力的&#xff0c;但具体而言还是有一些差别&#xff1b; 1&#xff1a;首先说Non-local&#xff0c;它是像素级别的self-attention,算的是图片中各个像素点对指定像素点的影响&#xff1b; 2&#xff1a;transformer我们拿s…

JVM产生FullGC的原因有哪些?

JVM产生FullGC的原因有哪些&#xff1f; 在Java虚拟机&#xff08;JVM&#xff09;中&#xff0c;垃圾回收&#xff08;Garbage Collection&#xff0c;简称GC&#xff09;是一个非常重要的机制。GC的目的是自动管理内存&#xff0c;回收不再使用的对象&#xff0c;防止内存泄…

揭秘!5大策略让广告变现长久有效

在数字化时代的浪潮下&#xff0c;广告变现作为自媒体和APP开发者重要的收入来源&#xff0c;越来越受到重视。 但如何让这种变现方式长久持续&#xff0c;成为许多内容创作者与平台运营者思考的问题。 本文旨在探讨广告变现的持久之道&#xff0c;通过分析前端展示、合规性、…

通过元学习优化增益模型的性能:基础到高级应用总结

在当今数据驱动的决策过程中&#xff0c;因果推断和增益模型扮演了至关重要的角色。因果推断帮助我们理解不同变量间的因果关系&#xff0c;而增益模型则专注于评估干预措施对个体的影响&#xff0c;从而优化策略和行动。然而&#xff0c;要提高这些模型的精确度和适应性&#…

lammps聚合物断键拉伸模拟

本文介绍聚合物的断键拉伸。 在lammps模拟中&#xff0c;所有的键默认是永久存在的&#xff0c;非正常情况下&#xff0c;不能断开&#xff0c;否则会产生"bond atoms missing”错误。 聚合物的拉伸模拟过程中&#xff0c;聚合物链并没有被拉断&#xff0c;而只是把不同的…

tmega128单片机控制的智能小车设计

第1章 绪论1.1 选题背景和意义 自第一台工业机器人诞生以来,机器人的民展已经遍及机械、电子、冶金、交通、宇航、国防等领域。近年来机器人的智能水平不断提高,并且迅速地改变着人们的生活方式。人们在不断探讨、改造、认识自然的过程中,制造能替代人工作的机器一…

国学诗词app开发,学古贯今,句句珠玑

“鹅鹅鹅&#xff0c;曲项向天歌。”这是很多人学会的第一首诗&#xff0c;国学诗词作为中华传统文化的重要组成部分&#xff0c;不仅在历史中占据重要地位&#xff0c;也是儿童学前启蒙的不二选择。对于家长来说&#xff0c;他们更喜欢在学前教孩子一些经典国学和古诗词&#…

180.二叉树:二叉搜索树(力扣)

代码解决 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* Tre…

好用的FTP客户端 Transmit 5中文

Transmit 5是一款专为macOS设计的FTP客户端软件&#xff0c;由Panic公司开发。它支持FTP、SFTP、WebDAV和Amazon S3等多种传输协议&#xff0c;满足用户多样化的文件传输需求。Transmit 5拥有用户友好的界面设计&#xff0c;提供了清晰的文件传输状态和详细的信息&#xff0c;让…

Java面经总结

一、java基础 1.重载和重写的区别 重载&#xff1a; 发生在同一类中&#xff0c;函数名必须一样&#xff0c;参数类型、参数个数、参数顺序、返回值、修饰符可以不一样。重写&#xff1a; 发生在父子类中&#xff0c;函数名、参数、返回值必须一样&#xff0c;访问修饰符必须…

【Android面试八股文】1. 你说一说Handler机制吧 2. 你知道Handler的同步屏障吗? 3. Looper一直在循环,会造成阻塞吗?为什么?

文章目录 一. 你说一说Handler机制吧二、你知道Handler的同步屏障吗&#xff1f;2.1 Handler消息的分类2.2 什么是同步屏障2.3 为什么要设计同步屏障2.4 同步屏障的用法 三、Looper一直在循环&#xff0c;会造成阻塞吗&#xff1f;为什么&#xff1f;扩展阅读 一. 你说一说Hand…