【“第二课堂”AI实践课堂笔记】:4__初识大模型

介绍

大模型的概念与特点

大模型通常指的是具有大规模参数和复杂架构的机器学习模型,尤其是在自然语言处理和计算机视觉等领域。

  1. 大模型的特点:
    参数数量巨大:可能包含数十亿甚至数万亿个参数,这使得它们能够学习到极其丰富和细致的模式和特征。
    强大的表示能力:能够对复杂的数据进行有效的表示和理解,捕捉到数据中的细微差别和复杂关系。
    泛化能力强:经过在大规模数据上的训练,可以对新的、未见过的数据做出较为准确的预测和处理。
  • 以自然语言处理中的大语言模型为例,它们能够:
    生成高质量的自然语言文本,如文章、故事、对话等。
    理解各种主题和领域的文本,并回答相关问题。
    进行语言翻译、摘要生成、情感分析等多种任务。
    一些著名的大模型如 GPT-4、文心一言等,在多个领域展现出了卓越的性能。
  1. 大模型的挑战和问题:
    计算资源需求高:训练和运行这样的模型需要大量的计算能力和内存,成本高昂。
    数据需求大:需要海量的高质量数据来进行有效的训练。
    可解释性差:其内部的决策过程和输出结果往往难以清晰地解释和理解。

尽管存在这些问题,大模型仍然是当前人工智能领域的研究热点和重要发展方向,为推动人工智能的发展和应用发挥了重要作用。

大模型的主要分类

  1. 自然语言处理模型
    像 GPT 系列、文心一言等,能够理解和生成人类语言,用于对话、文本生成、问答系统、机器翻译等任务。例如,在智能客服中,能够快速准确地回答用户的问题,提供帮助和解决方案。

  2. 计算机视觉模型
    例如 ResNet、VGG 等,用于图像识别、目标检测、图像分类、图像生成等任务。比如在自动驾驶中,识别道路标志、行人、车辆等,保障行车安全。

  3. 语音处理模型
    包括语音识别模型和语音合成模型。语音识别模型能够将人类的语音转化为文字,语音合成模型则可以将文字转换为自然流畅的语音。常见的应用如语音助手、语音导航等。

  4. 多模态模型
    可以同时处理多种类型的数据,如图像和文本、音频和文本等。比如能够理解图片内容并生成相应的文字描述。

  5. 强化学习模型
    常用于游戏、机器人控制、自动驾驶等需要通过与环境交互来学习最优策略的场景。 例如训练机器人通过不断尝试和学习,掌握复杂的操作技能。

  6. 推荐系统模型
    根据用户的历史行为和偏好,为用户推荐相关的产品、内容等。在电商平台上为用户推荐符合其兴趣的商品,提高用户购买的可能性。

  7. 预测分析模型
    基于历史数据进行预测,如预测股票价格、天气情况、销售趋势等。

不同类型的大模型在不同的应用场景中发挥着重要作用,并且随着技术的不断发展,新的类型和应用也在不断涌现。
例如,在医疗领域,可能会综合运用自然语言处理模型来理解病历,计算机视觉模型来分析医疗影像,预测分析模型来预测疾病的发展趋势;在电商领域,推荐系统模型可以根据用户的浏览和购买历史为其推荐商品,而预测分析模型可以预测商品的销售情况,以便进行库存管理。

接下来我以大语言模型和计算机视觉模型为例进行学习。

大语言模型(LLM)

大语言模型的特点

大语言模型具有以下显著特点

  1. 大规模参数:拥有海量的参数,例如数十亿甚至数千亿个。这使得它们能够学习到极其丰富和复杂的语言模式和语义表示。比如 GPT-3 就具有 1750 亿个参数。
  2. 广泛的知识覆盖:通过在大规模的文本数据上进行训练,涵盖了各种领域和主题的知识,能够回答各式各样的问题。
  3. 强大的语言理解能力:可以理解复杂的语言结构、语义关系和上下文信息,能够处理模糊、歧义的语言表达。
  4. 出色的生成能力:能够生成连贯、有逻辑且富有创造性的文本,例如文章、故事、对话等。
  5. 多任务处理能力:可以应用于多种自然语言处理任务,如文本分类、情感分析、机器翻译、摘要生成等,并且往往无需针对特定任务进行大量的重新训练。
  6. 上下文学习:能够根据给定的上下文信息来理解用户的需求,并生成相应的回答。
  7. 涌现能力:当模型规模达到一定程度时,会涌现出一些之前未被预期的能力,如零样本学习和少样本学习能力。

大语言模型的主要机制

大语言模型的主要机制包括以下几个方面

  1. 分词:将文本分解成词汇单元,如单词、子词或字符等,常用的分词工具有 nltkspacy(英文)和 jieba 库(中文)等。其中n-gram模型是一种基于分词的语言建模方法,它假设一个词出现的概率仅依赖于它前面的 n-1 个词,可以是 unigram(每个单词独立)、bigram(每个单词的概率取决于前一个单词)或 trigram(每个单词的概率取决于前两个单词)等形式,但 n-gram 模型存在忽略较长范围依赖关系和无法处理未见过词汇的局限性。
  2. 词向量:将词语转换成对应的数值向量表达形式,便于计算机读取和运算。常用方法包括独热编码和表示学习。独热编码将每个词汇表示为一个高维稀疏向量,其中只有一个元素为 1,其余为 0,但无法捕捉单词间的相似性和语义关系,且向量维度与词汇表大小相关,会导致向量十分稀疏。而表示学习则将词汇表中的每个单词映射到一个固定长度的低维向量空间中,相似的词汇具有相似的表示,从而捕获语义信息,它具有从高维到低维、能捕获语义信息、构建向量空间以及减小维度等特点。
  3. 神经概率语言模型:为解决词向量模式的局限性而引入神经网络,其具有强大的表达学习能力,词向量通过神经网络参数产生联系。例如 Transformer 模型,它由输入层、隐藏层和输出层构成。输入层接受上下文窗口内的词汇作为输入并表示为词向量;隐藏层通过学习权重捕获词汇之间的复杂关系,具备非线性建模能力;输出层使用 softmax 函数生成概率分布,表示词汇表中每个词汇作为下一个词的概率。
  4. 自注意力机制Transformer 中使用的一种特殊机制,它通过对输入序列进行线性变换,得到一个注意力权重分布,然后根据这个分布加权输入序列中的每个元素,得到最终的输出。其作用是让模型能够像人在阅读长文章时依靠注意力选择重点词进行关联从而更好地理解文章一样,对海量文本进行并行处理,提高处理速率。计算注意力权重的过程可以通过一套复杂的公式实现,简单来说,可以类比数学课本上关于向量的知识,当两个向量的方向趋于一致时,它们的点积数值越大,代表两个词的关联程度大;数值为 0 则表示两个向量垂直,即词之间没有关联;数值为负数则表示两个向量相反,即两个词不但没关联,还差距过大。在实际应用中,还需要经过多次重复和复杂计算以获取更准确的信息,确定每个词符合上下文语境的含义。

以“请注意垃圾分类”这句话为例,在Transformer中它会经历输入、编码器、解码器、输出四个阶段。句子被拆解输入到编码器后,编码器会对每个词生成初始表征;然后利用自注意力机制计算词与词之间的关联程度并打分;接着根据打分对初始表征进行加工;最后将加工过的表征输入到解码器,解码器根据对每个词的了解结合上下文输出翻译,期间每个词之间都可同时进行处理。

具体代码与分析

代码

以下代码的作用是:使用指定的预训练语言模型Qwen2-0.5B-Instruct进行文本生成。

  • 第一段(chat_cil.py) -> 实现了使用指定的预训练语言模型Qwen2-0.5B-Instruct,根据给定的提示"你是谁?"以及包含系统和用户角色的消息,生成一段新的文本,并最终打印输出。
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
from threading import Thread

device = "cuda"  # 设备,可以是 "cuda" 或 "cpu"

model_name = "/gemini/pretrain/Qwen2-0.5B-Instruct"
model = AutoModelForCausalLM.from_pretrained(model_name).to(device)
tokenizer = AutoTokenizer.from_pretrained(model_name)
streamer = TextIteratorStreamer(tokenizer)


messages = [
    {"role": "system", "content": "You are a helpful assistant."},
    # {"role": "user", "content": prompt}
]

def stream_generate(prompt, model, tokenizer, device):
    # 准备初始输入
    # messages = [
    #     {"role": "system", "content": "You are a helpful assistant."},
    #     {"role": "user", "content": prompt}
    # ]
    messages.append({"role": "user", "content": prompt})
    text = tokenizer.apply_chat_template(
        messages,
        tokenize=False,
        add_generation_prompt=True
    )
    model_inputs = tokenizer([text], return_tensors="pt").to(device)
    generate_params = dict(
        model_inputs,
        max_new_tokens=512,
        do_sample=True,
        top_k=50,
        temperature=0.7,
        pad_token_id=tokenizer.eos_token_id,
        streamer=streamer
    )
    
    thread = Thread(target=model.generate, kwargs=generate_params)
    thread.start()
    # 流式生成回复
    # generated_ids = model.generate(
    #     model_inputs.input_ids,
    #     max_new_tokens=512,
    #     do_sample=True,
    #     top_k=50,
    #     temperature=0.7,
    #     pad_token_id=tokenizer.eos_token_id
    # )
    

    generated_text = ""
    for new_text in streamer:
        generated_text += new_text
        print(new_text, end='', flush=True)
    print()
    # generated_text
    messages.append({"role": "user", "content": generated_text})
    # for output_id in generated_ids[0][model_inputs.input_ids.shape[-1]:]:
    #     token = tokenizer.decode(output_id, skip_special_tokens=True)
    #     generated_text += token
    #     print(token, end="", flush=True)
    # print()  # 打印新行以结束当前响应

# 多轮对话
while True:
    user_input = input("User: ")
    if user_input.lower() == 'exit':
        print("Exiting...")
        break
    
    # 生成回复并流式输出
    print("Assistant: ", end="")
    stream_generate(user_input, model, tokenizer, device)
  • 第二段(one_chat.py) -> 构建了一个基于streamlit的 Web 应用,用户在文本框中输入问题,应用会调用预训练模型生成回答,并以流式的方式在页面上逐步展示生成的内容。
import streamlit as st
from threading import Thread
import json
import time
from transformers import AutoTokenizer
from transformers import AutoModelForCausalLM, AutoTokenizer, TextIteratorStreamer
import torch

st.title('Qwen2-0.5B-Instruct')

device = "cuda"
model_name = "/gemini/pretrain/Qwen2-0.5B-Instruct"

@st.cache_resource
def get_model():  
    model = AutoModelForCausalLM.from_pretrained(model_name).to(device)
    tokenizer = AutoTokenizer.from_pretrained(model_name)
    return model, tokenizer

model, tokenizer = get_model()
streamer = TextIteratorStreamer(tokenizer, skip_prompt=True, skip_special_tokens=True)

def generate_response(input_text):

    prompt = f'''
    你是一个智能问答助手,这是你需要回答的问题:
    <question>
    {input_text}
    </question>
    '''

    print(prompt)
    # 构建消息列表
    messages = [{"role": "user", "content": prompt}]

    text = tokenizer.apply_chat_template(
        messages,
        tokenize=False,
        add_generation_prompt=True
    )
    model_inputs = tokenizer([text], return_tensors="pt").to(device)
    generate_params = dict(
        inputs=model_inputs.input_ids,
        max_new_tokens=512,
        do_sample=True,
        top_k=50,
        temperature=0.7,
        pad_token_id=tokenizer.eos_token_id,
        streamer=streamer
    )
    
    thread = Thread(target=model.generate, kwargs=generate_params)
    thread.start()

    return streamer

with st.form('my_form'):
    text = st.text_area('Enter text:', 'What are the three key pieces of advice for learning how to code?')
    submitted = st.form_submit_button('Submit')
    if submitted:
        message_placeholder = st.empty()
        # 调用模型生成响应
        streamer = generate_response(text)
        response = ""
        for text in streamer:
            response += text
            message_placeholder.info(response + "▌")
    
        message_placeholder.info(response)
  • 第三段(test.py) -> 与第一段代码类似,也是使用指定的预训练模型和提示,生成一段文本,不过在生成新的标记 ID 后,对其进行了特定的处理,以得到最终的输出并打印。
from transformers import AutoModelForCausalLM, AutoTokenizer
device = "cuda" # the device to load the model onto

model = AutoModelForCausalLM.from_pretrained(
    "/gemini/pretrain/Qwen2-0.5B-Instruct",
    torch_dtype="auto",
    device_map="auto"
)
tokenizer = AutoTokenizer.from_pretrained("/gemini/pretrain/Qwen2-0.5B-Instruct")

prompt = "你是谁?"
messages = [
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": prompt}
]
text = tokenizer.apply_chat_template(
    messages,
    tokenize=False,
    add_generation_prompt=True
)
model_inputs = tokenizer([text], return_tensors="pt").to(device)

generated_ids = model.generate(
    model_inputs.input_ids,
    max_new_tokens=512
)
generated_ids = [
    output_ids[len(input_ids):] for input_ids, output_ids in zip(model_inputs.input_ids, generated_ids)
]

response = tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]

print(response)

知识点

  • prompt

在大语言模型(LLM)中,prompt(提示词或提示信息)是指用户向模型提供的输入文本或指令,用于引导模型生成特定类型的响应。它就像是给模型的一个引导或指示,帮助模型理解用户的需求并按照期望生成输出。

prompt 的内容和结构可以有多种形式。它可以是一个简单的问题,如“地球的半径是多少?”;也可以是一段描述,如“描述一下春天的美丽景色”;还可以是一项具体的任务要求,如“为一款新的智能手机编写产品说明书”;甚至可以包含对话历史记录等信息。

通过不断优化和调整 prompt,用户可以引导模型生成更准确、高质量、符合特定需求的文本内容。不同的 LLM 对 prompt 的响应方式可能会有所差异,因此在使用时可能需要根据具体的模型进行一定的尝试和调整。

总之,prompt 在与 LLM 的交互中起着关键作用,它是用户与模型之间沟通的桥梁,能够帮助用户更好地利用 LLM 的能力来解决各种问题和完成各种任务。

  • 流式输出

流式输出是一种数据处理方式,它将数据以流的形式进行传输和处理。在这种方式中,数据不再集中存储在某个地方,而是以分散的方式存储在各个节点上,并不断流动。数据流的处理是在流动过程中实时完成的,这减少了数据处理的延迟,提高了数据处理效率。

在自然语言处理等领域,实现流式输出可以让模型实时地、连续地输出文本内容,而不是等待整个回答完全生成后再一次性输出,使用户体验更加流畅。例如,在与聊天机器人对话时,能够实时看到机器人逐字逐句地生成回答。

要实现流式输出,通常需要选择合适的编程语言和框架,在 Python 中,可以通过生成器Generator来实现流式输出。生成器是可以逐个产生值的函数,它可以在迭代过程中逐个产生数据。在处理大规模数据时,Python 的流式输出能够显著提高程序的性能和效率。

stable diffusion

介绍

Stable Diffusion 是一种强大的图像生成模型
Stable Diffusion 具有以下显著特点和优势:

  1. 高画质生成
    能够生成细节丰富、逼真清晰的图像。例如,可以生成极具艺术感的风景图像,其中的光影效果、色彩层次和物体纹理都十分细腻。
  2. 高度灵活的定制性
    用户可以通过输入各种提示词,包括主题、风格、色彩、构图等方面的描述,来精准控制生成图像的特征。比如,您可以要求生成一幅“赛博朋克风格的城市夜景,以蓝色和紫色为主色调,有飞行的汽车和摩天大楼”的图像。
  3. 快速生成
    相比一些传统的图像生成方法,Stable Diffusion 能够在相对较短的时间内生成图像,提高了创作效率。
  4. 多种应用场景
    被广泛应用于艺术创作、设计、影视制作、游戏开发等领域。比如,在游戏开发中为角色设计独特的外观,或者为影视作品创建概念艺术图。

实现效果

请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值