xld0932 发表于 2025-2-6 17:47

MM32与DeepSeek的融合:智能交互技术的突破与创新

#申请原创#   @21小跑堂

1.DeepSeek
2025春节期间,DeepSeek火了……DeepSeek是由杭州深度求索人工智能基础技术研究有限公司开发的大型语言模型,不仅性能超过ChatGPT,运行的成本还远低于它。DeepSeek目前提供了2种使用方式,一是通过网页在线或者是APP软件可以进行免费的对话,二是通过API开放平台与DeepSeek服务器进行对接交互。



2.网页版DeepSeek
我们可以通过打开DeepSeek官网(https://www.deepseek.com),点击开始对话,就可以跳转到DeepSeek网页版(https://chat.deepseek.com/),与DeepSeek进行交流了。这个是免费使用的,当前使用人也比较多,经常会出现服务器忙的提示……



3.DeepSeek API开放平台
通过DeepSeek的API开放平台,我们可以将DeepSeek应用到我们的应用程序当中,通过接口调用与DeepSeek之间完成交互;在DeepSeek在线接口文档(https://api-docs.deepseek.com/zh-cn/)中阐述了当前支持的开发方式有CURL、PYTHON、GO、NODEJS、RUBY、CSHARP、PHP、JAVA、POWERSHELL等等……
在使用DeepSeek API开发平台之前,我们需要先注册一个DeepSeek账号,然后在API开放平台中创建一个API key,这个API key就是我们通过其它开发软件连接到DeepSeek的凭证。

通过API开放平台使用DeepSeek是收费的,收费标准是根据每百万输出tokens来计费的;对于我们想体验一下通过API开放平台来操作DeepSeek的开发人员,DeepSeep赠送了10块钱的体验优惠,前期足够我们来熟悉了掌握DeepSeek的API开放平台开发了。



4.MM32与DeepSeek
想要MM32 MCU与DeepSeek之间实现交互,在接口层面我们可以使用CURL方式,通过HTTP协议与DeepSeek的API开放平台完成;在硬件层面,我们需要扩展网络模块与MM32进行连接,达到联网的功能。这里我们使用Air724这个4G模组,与MM32之间通过串口通讯,基于AT指令来进行联网、HTTP等功能的操作。

5.硬件连接
硬件连接如下图所示,将Air724接口的RXD与Mini-F5333开发板上Arduino接口的TXD进行连接,将Air724接口的TXD与Mini-F5333开发板上Arduino接口的RXD进行连接,将Air724接口的GND与Mini-F5333开发板上Arduino接口的GND进行连接,将Air724接口的RST与Mini-F5333开发板上Arduino接口的INT进行连接;同时给Air724模块供12V电源,给Mini-F5333开发板供5V电源。



6.功能实现
首先是基于Mini-F5333开发板创建基础工程,实现板载LED灯和KEY按键检测,通过移植MultiButton开源软件实现按键处理操作;通过AT指令操作来实现Air724模组的初始化配置,在按下按键后,实现HTTP与DeepSeek的交互;在接收到DeepSeek反馈的数据后,通过cJSON来进行解析;处理过程和解析的结果通过SWD接口打印到电脑监视软件上(这边是通过移植SEGGER_RTT来实现打印的)。具体的代码模块如下所示:

6.1.基础工程配置
#include "platform.h"
#include "SEGGER_RTT.h"

volatile uint32_t PLATFORM_DelayTick = 0;

void PLATFORM_InitSysTick(void)
{
    RCC_ClocksTypeDefRCC_Clocks;
    RCC_GetClocksFreq(&RCC_Clocks);

    if (SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000))
    {
      while (1)
      {
      }
    }

    NVIC_SetPriority(SysTick_IRQn, 0x0);
}

void PLATFORM_ConfigDelay(void)
{
    NVIC_InitTypeDef      NVIC_InitStruct;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);

    TIM_TimeBaseStructInit(&TIM_TimeBaseStruct);
    TIM_TimeBaseStruct.TIM_Prescaler         = (TIM_GetTIMxClock(TIM6) / 100000 - 1);
    TIM_TimeBaseStruct.TIM_CounterMode       = TIM_CounterMode_Up;
    TIM_TimeBaseStruct.TIM_Period            = (100 - 1);
    TIM_TimeBaseStruct.TIM_ClockDivision   = TIM_CKD_Div1;
    TIM_TimeBaseStruct.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStruct);

    TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE);

    NVIC_InitStruct.NVIC_IRQChannel = TIM6_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStruct);

    TIM_Cmd(TIM6, ENABLE);
}

void PLATFORM_DelayMs(uint32_t Tick)
{
    PLATFORM_DelayTick = Tick;

    while (PLATFORM_DelayTick)
    {
    }
}

void PLATFORM_InitConsole(void)
{
    SEGGER_RTT_ConfigUpBuffer(0, "RTTUP", NULL, 0, SEGGER_RTT_MODE_NO_BLOCK_SKIP);
}

int fputc(int ch, FILE *f)
{
    SEGGER_RTT_PutCharSkip(0, (char)ch);

    return (ch);
}

void PLATFORM_PrintClocks(void)
{
    printf("\r\nBOARD : Mini-F5333");
    printf("\r\nMCU   : MM32F5333D7P");
    printf("\r\n");

    switch (RCC->CFGR & RCC_CFGR_SWS_Msk)
    {
      case 0x00:
            printf("\r\nHSI used as system clock source");
            break;

      case 0x04:
            printf("\r\nHSE used as system clock source");
            break;

      case 0x08:
            if (RCC->PLL1CFGR & RCC_PLL1CFGR_PLL1SRC_Msk)
            {
                printf("\r\nPLL1 (clocked by HSE) used as system clock source");
            }
            else
            {
                printf("\r\nPLL1 (clocked by HSI) used as system clock source");
            }

            break;

      case 0x0C:
            printf("\r\nLSI used as system clock source");
            break;

      default:
            break;
    }

    RCC_ClocksTypeDefRCC_Clocks;
    RCC_GetClocksFreq(&RCC_Clocks);

    printf("\r\n");
    printf("\r\nSYSCLK Frequency : %7.3f MHz", (double)RCC_Clocks.SYSCLK_Frequency / (double)1000000.0);
    printf("\r\nHCLK   Frequency : %7.3f MHz", (double)RCC_Clocks.HCLK_Frequency   / (double)1000000.0);
    printf("\r\nPCLK1Frequency : %7.3f MHz", (double)RCC_Clocks.PCLK1_Frequency/ (double)1000000.0);
    printf("\r\nPCLK2Frequency : %7.3f MHz", (double)RCC_Clocks.PCLK2_Frequency/ (double)1000000.0);
    printf("\r\n");
}

void PLATFORM_Init(void)
{
    PLATFORM_InitSysTick();

    PLATFORM_ConfigDelay();

    PLATFORM_InitConsole();

    PLATFORM_PrintClocks();
}

void TIM6_IRQHandler(void)
{
    if (RESET != TIM_GetITStatus(TIM6, TIM_IT_Update))
    {
      if (PLATFORM_DelayTick)
      {
            PLATFORM_DelayTick--;
      }

      TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
    }
}

6.2.LED驱动
#include "bsp_led.h"

void bsp_LedInit(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);

    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_11 | GPIO_Pin_10 ;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
    GPIO_InitStruct.GPIO_Mode= GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB, &GPIO_InitStruct);

    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_7 | GPIO_Pin_6;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
    GPIO_InitStruct.GPIO_Mode= GPIO_Mode_Out_PP;
    GPIO_Init(GPIOC, &GPIO_InitStruct);

    GPIO_WriteBit(GPIOB, GPIO_Pin_11, Bit_SET);
    GPIO_WriteBit(GPIOB, GPIO_Pin_10, Bit_SET);
    GPIO_WriteBit(GPIOC, GPIO_Pin_7,Bit_SET);
    GPIO_WriteBit(GPIOC, GPIO_Pin_6,Bit_SET);
}

void bsp_LedToggle(uint8_t Index)
{
    switch (Index)
    {
      case 1:
            if (GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_11) == Bit_RESET)
            {
                GPIO_WriteBit(GPIOB, GPIO_Pin_11, Bit_SET);
            }
            else
            {
                GPIO_WriteBit(GPIOB, GPIO_Pin_11, Bit_RESET);
            }
            break;

      case 2:
            if (GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_10) == Bit_RESET)
            {
                GPIO_WriteBit(GPIOB, GPIO_Pin_10, Bit_SET);
            }
            else
            {
                GPIO_WriteBit(GPIOB, GPIO_Pin_10, Bit_RESET);
            }
            break;

      case 3:
            if (GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_7) == Bit_RESET)
            {
                GPIO_WriteBit(GPIOC, GPIO_Pin_7, Bit_SET);
            }
            else
            {
                GPIO_WriteBit(GPIOC, GPIO_Pin_7, Bit_RESET);
            }
            break;

      case 4:
            if (GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_6) == Bit_RESET)
            {
                GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_SET);
            }
            else
            {
                GPIO_WriteBit(GPIOC, GPIO_Pin_6, Bit_RESET);
            }
            break;

      default:
            break;
    }
}



6.3.KEY驱动
#include "bsp_key.h"

void bsp_KeyInit(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);

    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin= GPIO_Pin_4;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;
    GPIO_Init(GPIOC, &GPIO_InitStruct);

    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin= GPIO_Pin_5;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOC, &GPIO_InitStruct);

    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin= GPIO_Pin_1 | GPIO_Pin_2;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOB, &GPIO_InitStruct);
}

uint8_t bsp_KeyReadPinLevel(uint8_t Index)
{
    uint8_t PinLevel = 0;

    switch (Index)
    {
      case 1:
            PinLevel = GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_4);
            break;

      case 2:
            PinLevel = GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_5);
            break;

      case 3:
            PinLevel = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1);
            break;

      case 4:
            PinLevel = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_2);
            break;

      default:
            break;
    }

    return (PinLevel);
}



6.4.按键应用
#include "key.h"
#include "bsp_key.h"
#include "multi_button.h"

struct Button K1;
struct Button K2;
struct Button K3;
struct Button K4;

volatile uint8_t KeyRegisterFlag = 0;
volatile uint8_t KeyHttpPostFlag = 0;

void KEY_PressUpHandler(void *btn)
{
    struct Button *handle = (struct Button *)btn;

    switch (handle->button_id)
    {
      case 1:
            printf("\r\nK1");
            break;

      case 2:
            printf("\r\nK2");
            break;

      case 3:
            printf("\r\nK3");
            break;

      case 4:
            printf("\r\nK4");   KeyHttpPostFlag = 1;
            break;

      default:
            break;
    }
}

void KEY_Init(void)
{
    button_init(&K1, bsp_KeyReadPinLevel, Bit_SET,   1);
    button_init(&K2, bsp_KeyReadPinLevel, Bit_RESET, 2);
    button_init(&K3, bsp_KeyReadPinLevel, Bit_RESET, 3);
    button_init(&K4, bsp_KeyReadPinLevel, Bit_RESET, 4);

    button_attach(&K1, PRESS_UP, KEY_PressUpHandler);
    button_attach(&K2, PRESS_UP, KEY_PressUpHandler);
    button_attach(&K3, PRESS_UP, KEY_PressUpHandler);
    button_attach(&K4, PRESS_UP, KEY_PressUpHandler);

    button_start(&K1);
    button_start(&K2);
    button_start(&K3);
    button_start(&K4);

    KeyRegisterFlag = 1;
}

void SysTick_Handler(void)
{
    if (KeyRegisterFlag)
    {
      button_ticks();
    }
}


6.5.Air724驱动
#include "bsp_air724.h"
#include "platform.h"

uint8_tAir724_RxBuffer;
uint16_t Air724_RxLength = 0;
char   deepseek_Buffer;

void bsp_Air724InitUART(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    NVIC_InitTypeDef NVIC_InitStruct;
    UART_InitTypeDef UART_InitStruct;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);

    UART_StructInit(&UART_InitStruct);
    UART_InitStruct.BaudRate      = 115200;
    UART_InitStruct.WordLength    = UART_WordLength_8b;
    UART_InitStruct.StopBits      = UART_StopBits_1;
    UART_InitStruct.Parity      = UART_Parity_No;
    UART_InitStruct.HWFlowControl = UART_HWFlowControl_None;
    UART_InitStruct.Mode          = UART_Mode_Rx | UART_Mode_Tx;
    UART_Init(UART4, &UART_InitStruct);

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);

    GPIO_PinAFConfig(GPIOC, GPIO_PinSource0, GPIO_AF_8);
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource1, GPIO_AF_8);

    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_0;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
    GPIO_InitStruct.GPIO_Mode= GPIO_Mode_AF_PP;
    GPIO_Init(GPIOC, &GPIO_InitStruct);

    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin= GPIO_Pin_1;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOC, &GPIO_InitStruct);

    UART_ITConfig(UART4, UART_IT_RX, ENABLE);

    NVIC_InitStruct.NVIC_IRQChannel = UART4_IRQn;
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStruct);

    UART_Cmd(UART4, ENABLE);
}

void bsp_Air724RxIrqHandler(uint8_t Data)
{
    printf("%c", Data);

    Air724_RxBuffer = Data;

    Air724_RxLength += 1;
    Air724_RxLength %= 2048;
}

void bsp_Air724InitGPIO(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOI, ENABLE);

    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_0;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
    GPIO_InitStruct.GPIO_Mode= GPIO_Mode_Out_PP;
    GPIO_Init(GPIOI, &GPIO_InitStruct);

    GPIO_WriteBit(GPIOI, GPIO_Pin_0, Bit_SET);
}

void bsp_Air724Reset(void)
{
    GPIO_WriteBit(GPIOI, GPIO_Pin_0, Bit_SET);
    PLATFORM_DelayMs(100);

    GPIO_WriteBit(GPIOI, GPIO_Pin_0, Bit_RESET);
    PLATFORM_DelayMs(100);
}

void bsp_Air724ClearRxBuffer(void)
{
    Air724_RxLength = 0;

    for (uint16_t i = 0; i < 2048; i++)
    {
      Air724_RxBuffer = 0;
    }
}

void bsp_Air724Init(void)
{
    bsp_Air724InitUART();

    bsp_Air724InitGPIO();

    bsp_Air724ClearRxBuffer();
}

void bsp_Air724SendData(uint8_t Data)
{
    UART_SendData(UART4, Data);

    while (RESET == UART_GetFlagStatus(UART4, UART_FLAG_TXC))
    {
    }
}

uint32_t bsp_Air724SendCommandBlocking(char *Command, char *Response, uint32_t Timeout)
{
    if (Command != NULL)
    {
      while (*Command != '\0')
      {
            bsp_Air724SendData(*Command++);
      }

      bsp_Air724SendData(0x0D);
      bsp_Air724SendData(0x0A);
    }

    if (Timeout != 0)
    {
      bsp_Air724ClearRxBuffer();

      while (Timeout--)
      {
            if (strstr((char *)Air724_RxBuffer, Response) != NULL)
            {
                return (Timeout);
            }

            PLATFORM_DelayMs(1);
      }
    }

    return (0);
}

void bsp_Air724InputDataNonBlocking(char *Data)
{
    if (Data != NULL)
    {
      while (*Data != '\0')
      {
            bsp_Air724SendData(*Data++);
      }

      bsp_Air724SendData(0x1A);
    }
}

6.6.HTTP初始化
void HTTP_Init(void)
{
    bsp_Air724Reset();

    bsp_Air724SendCommandBlocking(NULL, "RDY",   10000);
    bsp_Air724SendCommandBlocking(NULL, "+NITZ", 10000);

    PLATFORM_DelayMs(500);

    bsp_Air724SendCommandBlocking("AT", "OK", 10000);

    bsp_Air724SendCommandBlocking("AT+CPIN?","OK", 10000);

    bsp_Air724SendCommandBlocking("AT+CGATT?", "OK", 10000);

    bsp_Air724SendCommandBlocking("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"", "OK", 10000);

    bsp_Air724SendCommandBlocking("AT+SAPBR=3,1,\"APN\",\"\"", "OK", 10000);

    bsp_Air724SendCommandBlocking("AT+SAPBR=1,1", "OK", 10000);

    bsp_Air724SendCommandBlocking("AT+SAPBR=2,1", "OK", 10000);

    bsp_Air724SendCommandBlocking("AT+CGNSPWR=1", "OK", 10000);

    bsp_Air724SendCommandBlocking("AT+CSQ", "OK", 10000);

    bsp_Air724SendCommandBlocking("AT+CGNSAID=31,1,1,1", "OK", 10000);
}

6.7.HTTP与DeepSeek交互
char POST_DATA[] =
"{\
    \"model\": \"deepseek-chat\",\
    \"messages\": [{\"role\": \"user\", \"content\": \"who are you?\"}],\
    \"stream\": false\
}";

void HTTP_Post(void)
{
    char Command;

    bsp_Air724SendCommandBlocking("AT+HTTPINIT", "OK", 10000);

    bsp_Air724SendCommandBlocking("AT+HTTPSSL=1", "OK", 10000);

    bsp_Air724SendCommandBlocking("AT+HTTPPARA=\"CID\",1", "OK", 10000);

    bsp_Air724SendCommandBlocking("AT+HTTPPARA=\"URL\",\"https://api.deepseek.com/chat/completions\"", "OK", 10000);

    bsp_Air724SendCommandBlocking("AT+HTTPPARA=\"CONTENT\",\"application/json\"", "OK", 10000);

    bsp_Air724SendCommandBlocking("AT+HTTPPARA=\"USERDATA\",\"Authorization:Bearer API key\"", "OK", 10000);

    memset(Command, 0, sizeof(Command));
    sprintf(Command, "AT+HTTPDATA=%d,10000", strlen(POST_DATA));

    bsp_Air724SendCommandBlocking(Command, "DOWNLOAD", 30000);

    printf("\r\n%s", POST_DATA);

    bsp_Air724InputDataNonBlocking(POST_DATA);

    bsp_Air724SendCommandBlocking("AT+HTTPACTION=1", "OK", 30000);

    bsp_Air724SendCommandBlocking(NULL, "+HTTPACTION: 1,200,", 30000);

    bsp_Air724SendCommandBlocking("AT+HTTPREAD", "OK", 30000);

    bsp_Air724RxHandler();

    bsp_Air724SendCommandBlocking("AT+HTTPTERM", "OK", 10000);
}

6.8.DeepSeek数据处理
#include "cJSON.h"

void bsp_Air724RxHandler(void)
{
    uint16_t Count = 0;
    uint16_t Group = 0;

    memset(deepseek_Buffer, 0, sizeof(deepseek_Buffer));

    for (uint16_t i = 0; i < Air724_RxLength; i++)
    {
      if (Air724_RxBuffer == '{')
      {
            Group++;
      }

      if (Group)
      {
            deepseek_Buffer =Air724_RxBuffer;
      }

      if (Air724_RxBuffer == '}')
      {
            if(Group) Group--;
      }
    }

    printf("\r\n--------------------------------------------------------------------------------");

    cJSON *cjson = cJSON_Parse(deepseek_Buffer);

    char *json_data = cJSON_Print(cjson);

    if (cjson == NULL)
    {
      printf("\r\ncjson error!!!");
    }
    else
    {
      printf("\r\n%s", json_data);
    }

    printf("\r\n--------------------------------------------------------------------------------");

    printf("\r\n");
}



7.运行结果
MCU向DeepSeek发送了"who are you?"的提问,如下图,DeepSeek进行了回答“I’m an AI language model created by OpenAI……”



8.附件
软件工程代码:

chenjun89 发表于 2025-2-6 18:03

deepseek可以本地离线部署应用

xld0932 发表于 2025-2-6 21:33

chenjun89 发表于 2025-2-6 18:03
deepseek可以本地离线部署应用

是的,是可以直接在电脑上本地部署使用的;但如何让MCU与本地部署的deepseek实现交互,还需要研究一下,不知是否可行;对于有算力的嵌入式平台则可以直接部署deepseek,对于MCU这种资源和算力不够的,通过上述的方式是不错的应用方案了……

xionghaoyun 发表于 2025-2-7 13:52

万恶的资本家 要开始收费了?

keer_zu 发表于 2025-2-7 13:57

不错,本地部署也可以尝试一下

keer_zu 发表于 2025-2-7 13:58

希望能发掘更多应用场景,更加实用的

xld0932 发表于 2025-2-7 14:00

keer_zu 发表于 2025-2-7 13:58
希望能发掘更多应用场景,更加实用的

xld0932 发表于 2025-2-7 14:02

keer_zu 发表于 2025-2-7 13:57
不错,本地部署也可以尝试一下

后面会专门分享一下如何实施本地部署的

wyde518 发表于 2025-2-8 16:05

xionghaoyun 发表于 2025-2-7 13:52
万恶的资本家 要开始收费了?

愤青{:lol:}

wsnsyy 发表于 2025-2-15 15:33

xionghaoyun 发表于 2025-2-7 13:52
万恶的资本家 要开始收费了?

做生意不收钱?

forgot 发表于 2025-2-17 09:49

本地部署好像对资源要求挺高的哦

weifeng90 发表于 2025-2-17 18:52

感觉deepseek之所以会火,在于开源免费,当然免费也是当前,后面形成粘性了估计就要开始收费了,毕竟企业要生存。

xld0932 发表于 2025-2-17 21:29

weifeng90 发表于 2025-2-17 18:52
感觉deepseek之所以会火,在于开源免费,当然免费也是当前,后面形成粘性了估计就要开始收费了,毕竟企业要 ...

App、网页版、离线部署的环境,这3个当前都是免费的;但通过调用API keys的方式是收费的,价格按照“百万Tokens”为单位进行计费的,先充值,后使用。但是当前官网上出了公告:“当前服务器资源紧张,为避免对您造成业务影响,我们已暂停 API 服务充值。存量充值金额可继续调用,敬请谅解!”,等后面可以充值了,才能再使用API keys的方式了……
页: [1]
查看完整版本: MM32与DeepSeek的融合:智能交互技术的突破与创新