开学在即,同学们都在期待新学期的到来,而老师们正在为开学第一课紧张地准备。作为英语老师,主要的一个任务就是帮助学生通过四六级考试,而考试对学生的词汇量的要求在4500-5000词,比高中阶段要提升1000-1500词,而且这些词大多涉及校园、职场、学术等专业场合,单词比较长,词汇内涵抽象,记忆起来有难度,这给教师课堂的词汇教学带来了不小的挑战。传统课堂依赖的是官方课件、词汇表,通过语音、单词扩展、例句讲解来讲授单词,如果单词比较孤立,没有附加场景,没有语音、图片等多模态手段的加持,想加深学生理解,吸引大学生的注意力就存在一定难度。

为了改革课堂教学,活跃课堂氛围,我本学期会引入音乐、图片、视频等附加内容,利用AI智慧教学手段和语料库技术来改进我的教学方式方法,让更多的学生沉浸到英语学习中,力争让学生把四六级单词记得更深更牢。

我教这本《新世纪大学英语(第二版)》配有课件、视频和文本等教学素材,唯独没有相关的词汇的相关图片。考虑到学生刚来,一下引入较为抽象的内容,会给学生带来畏难情绪。因此,我考虑采用讯飞的文生图功能,制作词汇图片,配合单词的词缀、音标、语境和谐音等帮助学生尽快适应大学英语的学习节奏,掌握单词记忆的技巧。

讯飞是国内领先的AI企业,它曾经在语音识别方面大杀四方,它的语音输入软件、中小学智能AI学习机等产品在国内有很高的声誉。而且,经常过尝试我发现讯飞的文生图一年有免费5000点的额度,每制作一幅图消耗6点,相当于可以制作近1000张图片。

一、注册网站,认证信息

首先,我们讯飞主页https://xinghuo.xfyun.cn/,可以看到讯飞星火的认知大模型提供API免费调用,而且不限量。

二、申请应用和免费额度

我们点击【API免费使用】——【服务管理】,在这期间你需要手机注册网站,并通过实名认证,这样才可以完整使用它的服务。接下来,我们在控制台——【我的应用】这里创建一个应用名称,加红色星号都需要填写。

新建应用

创建成功以后,我们就得到了一个APPID,后面我们用Python调用API时就会用到。接下来,我们点击应用名称,进入到控制台,在左侧【星火认知大模型】栏下面找到【图片生成】,点击【实时用量】下面的【立即购买】。

免费获取API额度

我们可以选择最前面的【免费包】,前提是你需要个人认证,再勾选最下面的【服务协议】,最后点确认下单,就可以拿到讯飞星火免费的文本图免费额度了。

选择套餐

由于文生图是特殊产品,厂家默认只让免费申请一个应用,多个应用不能重复申请。申请成功后,我们可以看到自己的免费额度、有效期、QPS等信息。这里QPS是Query Per Second的缩写,其实就是每秒可以发起的请求,这里是2次,对于个人用户来说已经够用了。

获取接口认证信息

三、下载样例,修改代码

接下来,我们在右下角找到API的操作【文档】,下载Python操作文生图的样例。

获取Python样例代码


我们得到了样例word2picture.py,用thonny软件打开后,找到最下方的API信息处,填写API的websocket接口信息。

填写认证信息


然后,运行该样例可以得到下面的默认图片,你可以适当添加图片比例和风格限制。目测生图速度比较快,默认会把图片生成到D盘的根目录。

获取默认生成图

这样,我们初步申请了讯飞的API,同时也得到了免费额度,生成了图片,下面我们进一步修改,第一是修改图片保存位置为当前目录的images文件夹下,另外生图让它批量生成,名称就是单词本身,另外提示词也可以优化一下适合课堂教学。

至于提示词,我们可以自己先写一个,然后让讯飞进行润色,得到不同风格的提示词。

调试提示词

测试后,我们得到mascot(吉祥物)的图片,这样一张生动活泼的图片可以给学生留下深刻的印象,辅助学生牢记它的语议。由于讯飞图片中带文字会乱码,所以就给它设定成不显示单词拼写。

Mascot文生图

为了批量生成图片,我们把代码优化,可以批量读取words.txt中的单词,进行图片批量生成。而这一过程也不需要人工去改,只需要向大模型描述清楚,让大模型修改即可。

修改代码

最后修改代码如下:

# encoding: UTF-8
import os
import time
import requests
from datetime import datetime
from wsgiref.handlers import format_date_time
from time import mktime
import hashlib
import base64
import hmac
from urllib.parse import urlencode
import json
from PIL import Image
from io import BytesIO
class AssembleHeaderException(Exception):
    def __init__(self, msg):
        self.message = msg
class Url:
    def __init__(this, host, path, schema):
        this.host = host
        this.path = path
        this.schema = schema
        pass
# calculate sha256 and encode to base64
def sha256base64(data):
    sha256 = hashlib.sha256()
    sha256.update(data)
    digest = base64.b64encode(sha256.digest()).decode(encoding='utf-8')
    return digest
def parse_url(requset_url):
    stidx = requset_url.index("://")
    host = requset_url[stidx + 3:]
    schema = requset_url[:stidx + 3]
    edidx = host.index("/")
    if edidx <= 0:
        raise AssembleHeaderException("invalid request url:" + requset_url)
    path = host[edidx:]
    host = host[:edidx]
    u = Url(host, path, schema)
    return u
# 生成鉴权url
def assemble_ws_auth_url(requset_url, method="GET", api_key="", api_secret=""):
    u = parse_url(requset_url)
    host = u.host
    path = u.path
    now = datetime.now()
    date = format_date_time(mktime(now.timetuple()))
    # print(date)
    # date = "Thu, 12 Dec 2019 01:57:27 GMT"
    signature_origin = "host: {}\ndate: {}\n{} {} HTTP/1.1".format(host, date, method, path)
    # print(signature_origin)
    signature_sha = hmac.new(api_secret.encode('utf-8'), signature_origin.encode('utf-8'),
                             digestmod=hashlib.sha256).digest()
    signature_sha = base64.b64encode(signature_sha).decode(encoding='utf-8')
    authorization_origin = "api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"" % (
        api_key, "hmac-sha256", "host date request-line", signature_sha)
    authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8')
    # print(authorization_origin)
    values = {
        "host": host,
        "date": date,
        "authorization": authorization
    }
    return requset_url + "?" + urlencode(values)
# 生成请求body体
def getBody(appid, text):
    body = {
        "header": {
            "app_id": appid,
            "uid": "123456789"
        },
        "parameter": {
            "chat": {
                "domain": "general",
                "temperature": 0.5,
                "max_tokens": 4096
            }
        },
        "payload": {
            "message": {
                "text": [
                    {
                        "role": "user",
                        "content": text
                    }
                ]
            }
        }
    }
    return body
# 发起请求并返回结果
def main(text, appid, apikey, apisecret):
    host = 'http://spark-api.cn-huabei-1.xf-yun.com/v2.1/tti'
    url = assemble_ws_auth_url(host, method='POST', api_key=apikey, api_secret=apisecret)
    content = getBody(appid, text)
    response = requests.post(url, json=content, headers={'content-type': "application/json"}).text
    return response
#将base64 的图片数据存在本地
def base64_to_image(base64_data, save_path):
    # 解码base64数据
    img_data = base64.b64decode(base64_data)
    # 将解码后的数据转换为图片
    img = Image.open(BytesIO(img_data))
    # 保存图片到本地
    img.save(save_path)
# 解析并保存到指定位置
def parser_Message(message):
    data = json.loads(message)
    # print("data" + str(message))
    code = data['header']['code']
    if code != 0:
        print(f'请求错误: {code}, {data}')
    else:
        text = data["payload"]["choices"]["text"]
        imageContent = text[0]
        # if('image' == imageContent["content_type"]):
        imageBase = imageContent["content"]
        imageName = data['header']['sid']
        savePath = f"images/{word}.jpg"
        base64_to_image(imageBase, savePath)
        print("图片保存路径:" + savePath)
if __name__ == '__main__':
    # 确保images目录存在
    if not os.path.exists('images'):
        os.makedirs('images')
    #运行前请配置以下鉴权三要素,获取途径:https://console.xfyun.cn/services/tti
    APPID = 'XXXXXX'
    APISecret = 'XXXX'
    APIKEY = 'XXXXX'
    # 读取words.txt中的单词
    with open('words.txt', 'r', encoding='utf-8') as f:
        words = [line.strip() for line in f if line.strip()]
    for word in words:
        desc = f'''创作一张英文单词{word}主题的图卡,图片上不要带字母或文字。采用4:3的图片比例。画面生动鲜活,融入人生、环境、职业等生活元素,突出人物或场景,巧妙展现单词内涵,易于理解和辨识,为记忆该单词增添助力。'''
        res = main(desc, appid=APPID, apikey=APIKEY, apisecret=APISecret)
        # 保存到指定位置
        parser_Message(res)

实践证明,文生图时,名词、动词具有生动形象的意义,生成的图较好,形容词和副词较弱。

四、总结

  1. 随着大模型的不断演进,文生图的速度和质量都在不断提高,豆包、星火、灵犀都在提供文生图的功能,大家可以去尝试一下。
  2. Python在文生图的过程中起到了一个非常好的桥梁作用,可以批量调用文生图api,在无人职守的情况下,实现图生的快速生成,提升了效率。
  3. 本次操作的关键在于申请API额度、调试Python代码和优化提示词这三个方面,只要按照我给的步骤一步一步来,你也一样可以很快地生成自己想要的图片。

关注我,让你的语言插上技术的翅膀!

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐