山东大学项目实训团队周报(三)

目录

一、任务概述

二、完成情况

2.1 前端

2.1.1 主页

2.1.2 对话

2.1.3 地图

2.2 后端

2.2.1 模型微调

2.2.2 文本转音频


一、任务概述

        这周我们的任务主要分为两部分:前端页面的代码编写 和 后端模型调试与音频生成。

        其中前端按照我们上周的原型设计,可以分为三个部分:主页、对话和地图部分,因此我们团队按这三个模块进行分工。

        后端部分则继续进行模型的微调,并且为了能够实现实时导游功能和语音对话功能,我们需要进行音频方面的尝试。

二、完成情况

2.1 前端

2.1.1 主页

        主页面的区域分布:

        可以看到,该页面主要由四部分组成分别是顶层的轮播图,中部的搜索区和功能区(景点介绍、天气情况等)以及底部的tabBar导航区。

        搜索区:

       搜索区有两行,第一行显示搜索图标与文字提示(没什么用起装饰作用),第二行为搜索框与搜索按钮。搜索框会将输入文本传给变量,搜索按钮会跳转相应所绑定的搜索函数。相应的在.js文件里写好相应的函数。

        功能区:

        功能区以2*2的结构放置了四个相应功能的跳转区域,我们通过wx:for语句循环放置相应的图片与文本介绍。在设置布局时,让每个区域水平、垂直对齐,同时每个占据50%的宽度,这样当放置四个区域时,就形成了2*2的布局。以下三张图分别为实现该区域的wxml、css、js文件。

2.1.2 对话

        对话模块我们采用“scroll-view"组件作为最外侧的父组件,以便对话框可以向下拉而不影响交互页面的显示。对内部每一次的对话,则使用"wx:for"进行循环处理,其中读取的列表中,设计"flag"标识符用以标志下面对话由用户发出还是由大模型发出。

<!--对话框模块-->
<scroll-view scroll-y class="box">
  <view wx:for="{{ dialogue }}" wx:key="id">
    <!--用户发出的信息-->
    <view class="user-dialogue" wx:if="{{ item.flag == 1 }}">
    </view>
    <!--AI回复的信息-->
    <view class="ai-dialogue" wx:if="{{ item.flag == 0 }}">
    </view>
  </view>
</scroll-view>

        以用户发出的信息为例,我们在父组件内放入三个组件,从左到右分别为 用户的语言 ,用以 模拟气泡的三角形用户的头像。三个组件并排放置,共同构成了类似微信对话的对话气泡。其中用以模拟气泡的尖的三角形。

/*气泡右边的小三角*/
.angle-right {
  border-top: 12rpx solid transparent;
  border-bottom: 12rpx solid transparent;
  border-left: 12rpx solid lightblue;
  margin-top: 3%;
  height: 1rpx;
}

2.1.3 地图

        中心点为趵突泉的地图构建。

<map 
longitude="{{defaultLongitude}}" latitude="{{defaultLatitude}}" 
scale="{{defaultScale}}" min-scale="{{minScale}}" max-scale="{{maxScale}}" 
style='height:{{windowHeight}}px' 
markers="{{stores}}" 
subkey="{{mapSubKey}}" 
show-compass="true" 
show-location="true" 
bindpoitap="poiTap">
</map>

         在map.wxml文件中引入如上组件,并填写属性值,属性值由下方定义。

module.exports = {
  "appName":"地图demo",
  "mapSubKey":"HZ-USOK-OGYUBN-DJUO-AFF",  //腾讯位置服务申请的key
  "center_longitude": 117.0165,  //趵突泉的经度,用作默认经度
  "center_latitude": 36.6616,  //趵突泉的纬度,用作默认纬度
  "min_scale":16,  //地图最小缩放大小
  "default_scale":17,  //地图默认缩放大小,设置为恰好可以看到趵突泉的大部分景点
  "max_scale":21  //地图最大缩放大小
}

        marker用来实现地点的标注,效果如下:

        很多时候需要获得地点的具体经纬度,这里提供一个方便的工具:腾讯地图坐标拾取器,可以通过点击方便的获取坐标。

2.2 后端

2.2.1 模型微调

        多模态任务分布广、种类多,预训练往往不能面面俱到。 VisualGLM 6B提供了一个小样本微调的例子,使用20张标注图增强模型回答“背景”问题的能力。

        解压数据&运行微调命令

        解压fewshot-data.zip以后运行如下命令:

bash finetune/finetune_visualglm.sh

        模型推理

        训练好以后可以使用如下命令推理: 

python cli_demo.py --from_pretrained your_checkpoint_path --prompt_zh 这张图片的背景里有什么内容?

        官方提供了fewshort数据集来对模型进行微调,使用20张标注图增强模型回答“背景”问题的能力。

        数据集为data.json格式,每张图片都具有img键指向图像存储路径,prompt提示均为“这图片的背景里有什么内容?”,label标签为图片的具体背景描述。模型通过读取图像,结合prompt引导模型聚焦label关注的内容。

        鉴于我们使用2张A100,决定使用LoRA微调,配置微调参数。

        bash finetune/finetune_visualglm.sh --layer_range 0 14 --lora_rank 10

        微调效果对比

        微调前:

   

欢迎使用 VisualGLM-6B 模型,输入图像URL或本地路径读图,继续输入内容对话,clear 重新开始,stop 终止程序
请输入图像路径或URL(回车进入纯文本对话): fewshot-data/2p.png
用户:这张图片的背景里有什么内容?
VisualGLM-6B:人们总是被生活琐事所困扰,无法摆脱束缚.
用户:clear
请输入图像路径或URL(回车进入纯文本对话): fewshot-data/meme.png
用户:这张图片的背景里有什么内容?
VisualGLM-6B:这张图片的背景是一张狗的图片,它躺在木地板上。
用户:clear
请输入图像路径或URL(回车进入纯文本对话): fewshot-data/passport.png
用户:这张图片的背景里有什么内容?
VisualGLM-6B:这张图片的背景是一台电脑键盘和两张护照。
用户:clear
请输入图像路径或URL(回车进入纯文本对话):

微调后:

欢迎使用 VisualGLM-6B 模型,输入图像URL或本地路径读图,继续输入内容对话,clear 重新开始,stop 终止程序
请输入图像路径或URL(回车进入纯文本对话): fewshot-data/2p.png
用户:这张图片的背景里有什么内容?
VisualGLM-6B:这张图片的背景是雨天,
用户:描述一下这张图片。
VisualGLM-6B:这张图片描绘了雨天的情景,雨水淅淅沥沥地落在地面上。人们穿着雨衣或雨伞,走在雨中,似乎在寻找着什么.
用户:clear
请输入图像路径或URL(回车进入纯文本对话): fewshot-data/meme.png
用户:这张图片的背景里有什么内容?
VisualGLM-6B:这张图片的背景是木质地板。
用户:什么颜色的地板
VisualGLM-6B:这张图片的背景是蓝色的。
用户:描述一下这张图片。
VisualGLM-6B:这张图片描绘了一只棕色的小狗躺在蓝色的木质地板上。
用户:clear
请输入图像路径或URL(回车进入纯文本对话): fewshot-data/passport.png
用户:这张图片的背景里有什么内容?
VisualGLM-6B:这张图片的背景是电脑键盘。
用户:描述一下这张图片。
VisualGLM-6B:这张图片的特点是电脑键盘和护照。
用户:有几张护照    
VisualGLM-6B:两张护照。
用户:clear
请输入图像路径或URL(回车进入纯文本对话):
2.2.2 文本转音频

        分词是将文本分割成单个单词或词组的过程。在英文等语言中,单词之间通常有空格分隔,因此分词相对简单。但在中文、日文等语言中,单词之间没有空格,需要使用分词算法来正确地识别单词边界。

        英文分词:

import nltk
nltk.download('punkt')
from nltk.tokenize import word_tokenize
 
text = "Hello, world! This is a text-to-speech example."
tokens = word_tokenize(text)
print(tokens)

        中文分词

import jieba
 
text = "你好,世界!这是一个文本转语音的示例。"
tokens = jieba.lcut(text)
print(tokens)

        词性标注是为每个单词分配适当的词性标签(如名词、动词、形容词等)。这是进一步语义分析和生成语音的基础。

import nltk
nltk.download('averaged_perceptron_tagger')
 
text = "Mr. Smith bought 300 apples."
tokens = nltk.word_tokenize(text)
pos_tags = nltk.pos_tag(tokens)
print(pos_tags)

        NER 是识别文本中命名实体(如人名、地名、组织名等)的过程。

import spacy
 
nlp = spacy.load("en_core_web_sm")
text = "Apple is looking at buying U.K. startup for $1 billion."
doc = nlp(text)
for ent in doc.ents:
    print(ent.text, ent.label_)

        处理非标准词是将文本中的特殊格式(如数字、缩写、日期等)转换为标准的书写形式,以便生成正确的语音。如数字转换:

from word2number import w2n
 
text = "I have 300 apples."
standard_text = text.replace("300", "three hundred")
print(standard_text)

        确定每个单词的发音、词性、重音模式等。这一步包括词汇转换(Lexical Conversion),也称为文本规范化(Text Normalization, TN)和音素转换(Phonetic Conversion)。

        文本规范化是将输入文本中的非标准词(如数字、缩写、符号等)转换为标准书写形式的过程。这是为了确保 TTS 系统能正确处理和发音这些词。

        音素转换是将标准化的文本转换为音素序列的过程。音素是语言的最小语音单位。这个步骤确保每个单词都能被准确发音。

        CMUDict 是一个广泛使用的英语发音词典,可以将单词转换为对应的音素序列。

import nltk
nltk.download('cmudict')
 
from nltk.corpus import cmudict
 
d = cmudict.dict()
 
def text_to_phonemes(text):
    words = text.split()
    phonemes = [d[word.lower()][0] for word in words if word.lower() in d]
    return phonemes
 
text = "Hello world"
phonemes = text_to_phonemes(text)
print(phonemes)

        词性和重音模式对生成自然流畅的语音至关重要。词性标注(POS tagging)可以帮助确定每个单词的词性,而重音模式则涉及确定哪些音节需要重读。

        重音模式可以通过音节和词典规则来确定。例如,CMUDict 包含音节的重音信息:

def get_stress_pattern(word):
    if word.lower() in d:
        phonemes = d[word.lower()][0]
        stress_pattern = ''.join([ph[-1] if ph[-1].isdigit() else '0' for ph in phonemes])
        return stress_pattern
    return None
 
word = "hello"
stress_pattern = get_stress_pattern(word)
print(stress_pattern)

        将处理后的文本转换成语音波形。这一步包括选择合适的音色、调整语速、语调和音量等。

        下面是一个使用Tacotron和WaveNet的示例代码,展示如何将文本转换为语音波形。

import torch
from transformers import Wav2Vec2ForCTC, Wav2Vec2Tokenizer
import numpy as np
import IPython.display as ipd
 
# 加载预训练的Tacotron模型
tacotron_model = Tacotron2.from_pretrained("tacotron2")
# 加载预训练的WaveNet模型
wavenet_model = WaveNet.from_pretrained("wavenet")
 
# 输入文本
text = "Hello, how are you?"
 
# 将文本转换为频谱图
spectrogram = tacotron_model(text)
 
# 将频谱图转换为语音波形
waveform = wavenet_model(spectrogram)
 
# 播放生成的语音
ipd.Audio(waveform.numpy(), rate=22050)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值