实践指南:EdgeOne与HAI的梦幻联动

这篇具有很好参考价值的文章主要介绍了实践指南:EdgeOne与HAI的梦幻联动。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在当今快速发展的数字时代,安全和速度已成为网络服务的基石。EdgeOne,作为腾讯云提供的边缘安全加速平台,以其全球部署的节点和强大的安全防护功能,为用户提供了稳定而高效的网络体验。而HAI(HyperApplicationInventor),腾讯云推出的高性能应用服务,通过其易用的图形化界面和丰富的模型库,使得AI应用开发变得触手可及。本文将探讨EdgeOne与HAI的结合如何为用户提供一个既安全又高效的AI应用开发环境。

EdgeOne:全球加速与安全防护

实践指南:EdgeOne与HAI的梦幻联动

  1. DDoS防护:EdgeOne使用Anycast架构在全球建立超过25个清洗中心,能快速检测并清除网络、传输和应用层的DDoS攻击。
  2. WEB攻击防护:EdgeOne拥有广泛的攻击特征库,覆盖主要的安全威胁,能阻止各类Web攻击并防御0day漏洞,通过AI提高检测准确性,减少误报。
  3. 智能CC识别:EdgeOne利用多年经验,通过分析网络流量和多种参数,自动识别并定位攻击源,有效对抗CC攻击。
  4. BOT防护:EdgeOne通过协议、IP和会话特征识别BOT,结合数据分析建立模型,防止恶意爬虫攻击,减少对正常爬虫的误伤。
  5. 攻击溯源:EdgeOne可以捕获并分析异常事件,提取攻击信息,提供监控页面展示攻击详情,帮助用户调整防护策略。
  6. 全天候监测:腾讯安全团队24/7实时监控,主动发现并应对威胁,快速响应安全事件。

不多说了,剩下的内容都已经在官方文档中有详细描述。就我们个人而言,EdgeOne具有以下主要优点,并且我也附上了需要的关键文档地址:

  • 干净流量计费模式:对于安全防护功能拦截的请求不进行计费。这种计费模式的优势在于,用户无需担心因网络攻击而产生的额外费用,可以更加专注于业务的发展和优化。
  • 免费证书:简化HTTPS部署,官方文档:https://cloud.tencent.com/document/product/1552/90437
  • 个人版套餐升级:CC防护与自定义规则设置,官方文档:https://cloud.tencent.com/document/product/1552/93128
  • 无域名接入:快速启用四层代理服务,这个得需要企业认证,个人慎选。官方文档:https://cloud.tencent.com/document/product/1552/96051
  • 自助诊断:快速定位问题,通过输入诊断链接,用户可以快速获得诊断报告和解决指引,从而提高问题解决的效率。官方文档:https://cloud.tencent.com/document/product/1552/81229
  • 折扣活动:年度最低价,性价比之选,官方文档:https://cloud.tencent.com/document/product/1552/96920
  • 无域名接入功能,快速接入 EdgeOne 启用四层代理服务。https://cloud.tencent.com/document/product/1552/96051

HAI:AI应用的快速开发

HAI提供了可视化交互界面,支持JupyterLab、WebUI等多种算力连接方式,使得用户即使没有深厚的编程背景也能轻松开发AI应用。这种“有手就能开发”的设计理念,极大地降低了AI技术的应用门槛。支持学术加速,通过线路自动择优,能够大幅提升主流学术资源平台的访问、下载速度。同时,HAI预装了StableDiffusion、ChatGLM等热门模型,用户可以在数分钟内构建自己的大语言模型、AI作画等应用环境。

这个话题不需要详细讨论了,我已经整理了开发中需要了解的主要优点和相关文档,以便大家能够快速入手开发:

  1. 快速部署:创建高性能应用服务实例,选择合适的地域、算力方案,并设置实例名称和硬盘空间。官方文档:https://cloud.tencent.com/document/product/1721/101036
  2. 生成API文档:在已部署的Stable Diffusion应用基础上,通过JupyterLab部署API服务。官方文档:https://cloud.tencent.com/document/product/1721/102198
  3. 模型下载地址:https://civitai.com/
  4. 导入外部模型:在腾讯云高性能应用服务HAI上,可以通过三种方式导入外部模型,但是为了花钱少一点,我推荐你选择COS存储。官方文档:https://cloud.tencent.com/document/product/1721/102523#1bb64c7b-0bc8-4a2a-86f0-ad0e71d8f059

联动开发

现在让我们来探讨一下为何可以采用联动开发的方式。我们的目标是以最为经济实惠的价格部署我们的AI绘画应用。

  1. HAI高性能服务器是按照小时收费的,所以我们很多情况下会选择关机,但是一旦重启服务器,外网IP就会变动,导致你的访问路径也就随之变换。但是这一步可以在EdgeOne中使用边缘函数解决。
  2. EdgeOne本身就已经对我们的服务器做了相应的安全防护。
  3. HAI高性能服务器,他是一个Ubuntu20.04环境的虚拟机,也就是说,我们已经有了一个服务器,只不过这个服务器被包装成了绘画AI应用,所以不要浪费掉。用起来

我们接下来看下我们会用到哪些技术:HTML、Javascript、CSS、Nginx、Python、边缘函数中的各个API、Linux基本命令。

准备环境

HAI高性能服务器

关于创建服务器的步骤,我就不再进行演示了,请直接查看官方教程,相关地址也已经提供。我们将重点演示以下内容:下载/上传模型、通过WEB UI演示AI绘画功能、下载并配置Nginx以监听80端口、启动API接口服务。

下载/上传模型

这一步我当时使用过如何官方默认的JupyterLab页面上传,速度是真的很可观~我直接放弃了。选择了COS对象存储。我们先去下载好看的模型。这里以https://civitai.com/ 为例。

实践指南:EdgeOne与HAI的梦幻联动

模型下载到本地之后,去创建COS对象存储服务。

如何创建这么简单的教程,我就不演示了,我们直接看上传和下载。这里创建存储桶的时候,所属地域一定要和你HAI绘画服务器在一起。否则会产生很多额外的花销。谨记~

实践指南:EdgeOne与HAI的梦幻联动

进入存储桶之后,直接点击页面的上传文件即可,请选择刚才下载的模型文件。上传的过程中不要动浏览器,一旦刷新和关闭浏览器就会前功尽弃。

实践指南:EdgeOne与HAI的梦幻联动

稍等片刻,然后点击模型文件的详情,进入基本信息页面。在这里,请确保将权限设置为公有读取,否则HAI服务器将无法下载到模型文件。然后,复制临时链接。

实践指南:EdgeOne与HAI的梦幻联动

我们进入已经创建好的HAI服务器。

实践指南:EdgeOne与HAI的梦幻联动

实践指南:EdgeOne与HAI的梦幻联动

实践指南:EdgeOne与HAI的梦幻联动

进入终端,使用一下几个命令,下载模型文件到模型文件夹。

cd stable-diffusion-webui/models/Stable-diffusion

wget 临时链接粘贴到此处

等待下载完毕。

WEB UI演示AI绘画

让我们前往WEB UI页面,尝试一下看看是否成功安装了。

实践指南:EdgeOne与HAI的梦幻联动

实践指南:EdgeOne与HAI的梦幻联动

在WEB UI页面上,选择您自己的模型文件,并使用一段神奇的提示词。当然,提示词越好,生成的结果也会越好。如果有任何不清楚的地方,您可以参考您下载的模型附带的教程。这样基本上就没有问题了。接下来,让我们再来看看如何让HAI提供站点服务。

Nginx站点配置

依然是同样的步骤,在JupyterLab中的终端中直接使用以下命令操作:

  1. 下载Nginx:使用命令 apt install nginx 进行安装。
  2. 启动Nginx:使用命令 service nginx start 启动服务。

当您直接使用IP地址在浏览器中访问后,如果显示以下界面,那就表示安装成功了。

实践指南:EdgeOne与HAI的梦幻联动

接下来,我们继续修改Nginx的配置文件:
使用以下命令编辑配置文件:

vim /etc/nginx/sites-available/default

然后,在文件中添加以下配置:

实践指南:EdgeOne与HAI的梦幻联动

# 配置/images路径的访问规则
location /images/  {
            add_header 'Access-Control-Allow-Origin' "$http_origin";
            add_header 'Access-Control-Expose-Headers' 'strict-origin-when-cross-origin';
            alias   /root/stable-diffusion-webui/outputs/star/images/;  # 你的静态页面
            expires 1d;
            }
location /sdapi/  {
      # Add CORS headers
     add_header 'Access-Control-Allow-Origin' '*' always;
     add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
     add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
    add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
    proxy_pass  http://127.0.0.1:7862/sdapi/;
    if ($request_method = "OPTIONS"){
            return 200;
        }
    }

这里配置了/images路径的访问规则以及API服务的代理。为什么要配置代理呢?这显然是因为绘画的API服务不支持跨域访问,所以我们添加了一个反向代理。由于我们的请求是POST非简单请求,因此浏览器还会发送一个OPTIONS的预检请求。我也做了相应的处理。以免跨域报错。

修改完成后,使用命令 service nginx reload 来重新加载Nginx的配置。您可以看到我们配置的/images路径对应的文件。这个路径您可以随心配置,只要确保其中包含您自己的图片即可。您可以选择自己维护这些图片,也可以通过程序生成。为了演示,我只简单复制了几张我使用AI绘画出来的图片。

实践指南:EdgeOne与HAI的梦幻联动

让我们通过Nginx来访问一下图片,以确保可以正常访问。

在浏览器中输入以下地址进行访问:http://你的IP/images/1.png

实践指南:EdgeOne与HAI的梦幻联动

接下来,我们继续调试API服务。请启动HAI绘画应用的API服务,使用以下命令:

python launch.py --nowebui --xformers --opt-split-attention --listen --port 7862

然后,在浏览器中输入IP地址和端口号,后面加上/docs路径即可正常访问路径了。

实践指南:EdgeOne与HAI的梦幻联动

让我们通过工具来测试一下,看看能否通过Nginx正常访问接口。你可以随意选择一个接口路径进行测试。我选择了一个简单的无请求参数的GET请求作为示例。通常情况下,这个请求会带有端口号。

实践指南:EdgeOne与HAI的梦幻联动

使用调试工具来调用一下Nginx配置的路径,确保一切正常。

实践指南:EdgeOne与HAI的梦幻联动

如果您还不确定的话,可以通过查看默认的Nginx访问路径来确认。您可以使用以下命令来实时查看日志:

tail -f /var/log/nginx/access.log

这样您就可以确定API是否能够被正确命中。

实践指南:EdgeOne与HAI的梦幻联动

启动API接口服务

为了解决Nginx每次关机后无法正常启动的难题,我们采取了一项巧妙的解决方案:将启动命令直接写入API启动服务接口中,从而确保服务能够在每次启动时正确配置Nginx。具体操作如下:首先,我们需要找到项目中的launch.py文件。一旦找到了该文件,我们只需在其中添加几行命令即可。这些命令将确保Nginx在服务器启动时得到正确的配置,并能够顺利启动。这种方法简单而高效,能够有效解决Nginx启动问题,保证服务的稳定性和可靠性。

实践指南:EdgeOne与HAI的梦幻联动

代码如下:

import subprocess

# 此处省略很多代码~~
def main():
    # 使用subprocess.run()执行命令
    result = subprocess.run(['service', 'nginx', 'start'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
    
    # 检查命令是否执行成功
    if result.returncode == 0:
        print("Nginx 已成功启动")
    else:
        print("启动 Nginx 时出错")
        print("错误信息:", result.stderr)
        
# 此处省略很多代码~~

为了验证我们的解决方案的有效性,让我们再次重新启动API服务,观察是否能够成功启动Nginx。

实践指南:EdgeOne与HAI的梦幻联动

通过以上步骤,我们的HAI高性能服务器已经完成了基本配置。无论进行多少次关机重启,我们的Nginx都会随着API接口一起启动,确保了系统的稳定性和可靠性。现在,让我们继续深入探讨EdgeOne的配置过程。

EdgeOne边缘函数

在配置EdgeOne时,首先需要确保完成无域名站点的配置,你可以直接参考官方文档进行操作。接着,我们需要创建边缘函数来实现相应的缓存处理。考虑到你没有企业版权限,因此无法使用四层加速,但可以通过边缘函数来达到类似的效果。关于边缘函数中代码的具体使用问题,我建议你仔细阅读官方文档,其中包含了详细的操作指南和示例代码,可以帮助你快速上手。你可以点击以下链接查看官方文档:EdgeOne 官方文档

实践指南:EdgeOne与HAI的梦幻联动

在配置边缘函数时,你可以选择Hello World模板作为起点,然后依次点击下一步进行配置。虽然选择了Hello World模板,但它只是一个起点,我们将在此基础上进行深入的定制,以实现我们所需要的功能。

实践指南:EdgeOne与HAI的梦幻联动

实践指南:EdgeOne与HAI的梦幻联动

完成所有配置后,系统会为你生成一个默认的域名。接下来,我们需要编写代码来实现功能。通常情况下,我会额外编写一个test函数,专门用于测试。当然,如果你觉得不需要,也可以忽略。在这次配置中,我们创建了两个边缘函数。这些函数已经经过我封装,通过最小的变动来应对HAI服务器外网IP的变化,确保了系统的稳定性和可靠性。

查询图片处理

一个绘画应用的关键之一在于能够提供优质的图片展示功能。毕竟,画作的视觉效果是吸引用户的关键之一。缺少了图片展示功能,这个应用就好比是一本没有插图的画册,缺乏吸引力,难以引起用户的兴趣。

async function fetchJquery(event, request) {
  const cache = caches.default;
  // 缓存没有命中,回源并缓存
  let response = await fetch(request);

  // 在响应头添加 Cahe-Control,设置缓存时长 10s
  response.headers.append('Cache-Control', 's-maxage=600');
  event.waitUntil(cache.put(request, response.clone()));

  // 未命中缓存,设置响应头标识
  response.headers.append('x-edgefunctions-cache', 'miss');
  return response;
}

async function handleEvent(event) {
  const urlInfo = new URL(event.request.url);
  var url = new URL(event.request.url);
  var ip = url.searchParams.get('ip');
  // 请求非图片资源
  if (!/\.(jpe?g|png)$/.test(urlInfo.pathname)) {
    return event.respondWith(new Response('Error thrown 没命中图片URL' + urlInfo.pathname));
  }
  // 资源地址,也作为缓存键
  const request = new Request(ip + urlInfo.pathname);
  // 缓存默认实例
  const cache = caches.default;

  try {
    // 获取关联的缓存内容,缓存过,接口底层不主动回源,抛出 504 错误
    let response = await cache.match(request);

    // 缓存不存在,重新获取远程资源
    if (!response) {
      return fetchJquery(event, request);
    }

    // 命中缓存,设置响应头标识
    response.headers.append('x-edgefunctions-cache', 'hit');

    return response;
  } catch (e) {
    await cache.delete(request);
    // 缓存过期或其他异常,重新获取远程资源
    return fetchJquery(event, request);
  }
}

addEventListener('fetch', (event) => {
  event.respondWith(handleEvent(event));
});

这段代码的主要功能是用于处理网络请求并管理资源的缓存策略,确保快速响应用户请求的同时,减少不必要的网络流量。

  1. fetchJquery 函数:
    • 该函数用于处理当资源未被缓存或缓存过期时的情况。
    • 使用fetch函数发起网络请求,获取资源的最新响应。
    • 在响应头中添加Cache-Control,设置资源在服务端缓存中的最长有效时间为600秒。
    • 使用cache.put方法将获取的响应克隆一份并存入缓存中,以便后续请求可以直接从缓存中获取。
    • 设置响应头x-edgefunctions-cachemiss,表示这是一个未命中缓存的请求。
    • 返回原始响应给请求者。
  2. handleEvent 函数:
    • 该函数用于检查请求的URL是否指向一个图片资源(通过文件扩展名判断)。
    • 如果请求的不是图片资源,将返回一个错误响应。
    • 如果是图片资源,尝试从缓存中获取请求的资源。
    • 如果缓存中存在资源,则设置响应头x-edgefunctions-cachehit,表示这是一个命中缓存的请求,并返回缓存中的资源。
    • 如果缓存中不存在资源或发生异常(如缓存过期),则删除缓存并重新调用fetchJquery函数获取资源。

在访问图片资源时,需要特别注意的是,我采用了路径后面的 IP 参数进行访问。这是因为 HAI 每次重启后外网 IP 都会发生变化,如果每次都要修改每个边缘函数的话,会相当繁琐。为了避免这种情况,我选择通过参数传递的方式来获取图片资源。这样一来,获取图片资源的边缘函数就不需要再进行任何修改了。另外,你还需要对匹配触发规则进行配置,比如我设置的规则是包含 "/images" 的路径才会触发相应的操作。

实践指南:EdgeOne与HAI的梦幻联动

在浏览器中输入默认域名,并随意添加 "/images/*.png" 即可访问相应图片,前提是该图片存储于我们的服务器上。现在让我们来观察一下效果。值得注意的是,这种方式的命中率并不是很高,所以在刚部署完边缘函数后,需要多刷新几次才能看到效果。

实践指南:EdgeOne与HAI的梦幻联动

静态网页

这个边缘函数专门用于处理用户交互。

const html = `
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>AI绘图</title>
    <style>
        body {
            font-family: Arial, sans-serif;
        }
        
        .container {
            display: flex;
            justify-content: center;
        }

        .box {
            margin: 20px;
            border: none; /* 移除框的边框 */
            padding: 10px;
            background-color: #f5f5f5; /* 设置框的背景颜色 */
            border-radius: 10px; /* 添加圆角 */
            display: flex; /* 使用flex布局 */
            flex-direction: column; /* 垂直布局 */
            align-items: center; /* 居中对齐 */
            text-align: center; /* 文字居中对齐 */
        }
        .box:nth-child(2) {
          align-self: start; /* 右边的box顶部对齐 */
        }

        .box-title {
            margin-bottom: 10px;
            margin-right: 500px;
            border-bottom: 1px solid grey; /* 添加标题底部的分隔线 */
            padding-bottom: 5px; /* 添加一些底部间距以增强视觉效果 */
        }

        #image-container {
            width: 512px;
            height: 512px;
            background-color: #eee;
            margin: auto; /* 在父元素中水平居中 */
        }

        #text-description {
            width: 300px;
            height: 100px;
            margin-bottom: 10px;
            border: 1px solid grey; /* 添加外边框 */
            padding: 5px;
            resize: none; /* 禁止调整大小 */
            font-size: 14px;
            outline: none; /* 移除输入框默认的外边框 */
            border-radius: 0; /* 移除圆角 */
        }
        
        #text-description2 {
            width: 300px;
            height: 100px;
            margin-bottom: 10px;
            border: 1px solid grey; /* 添加外边框 */
            padding: 5px;
            resize: none; /* 禁止调整大小 */
            font-size: 14px;
            outline: none; /* 移除输入框默认的外边框 */
            border-radius: 0; /* 移除圆角 */
        }
        
        #dropdown {
            padding: 10px 20px; /* 增大按钮的内边距 */
            cursor: pointer;
            margin-bottom: 10px;
            border: 1px solid grey; /* 添加外边框 */
            width: 100%; /* 将宽度设置为100%以与容器对齐 */
            align-self: flex-start; /* 按钮左对齐 */
        }
        
        #dropdown2 {
            padding: 10px 20px; /* 增大按钮的内边距 */
            cursor: pointer;
            margin-bottom: 10px;
            border: 1px solid grey; /* 添加外边框 */
            width: 100%; /* 将宽度设置为100%以与容器对齐 */
            align-self: flex-start; /* 按钮左对齐 */
        }
        
        #acckey {
            padding: 10px 20px; /* 增大按钮的内边距 */
            cursor: pointer;
            margin-bottom: 10px;
            border: 1px solid grey; /* 添加外边框 */
            width: 100%; /* 将宽度设置为100%以与容器对齐 */
            align-self: stretch; /* 按钮左对齐 */
        }

        #input-container {
            flex-grow: 1;
            display: flex;
            flex-direction: column; /* 垂直布局 */
            align-items: center; /* 居中对齐 */
        }

        #text-input {
            width: 300px;
            height: 30px;
            margin-bottom: 10px;
        }

        #generate-button {
            padding: 10px 20px; /* 增大按钮的内边距 */
            background-color: #4caf50;
            color: white;
            border: none;
            cursor: pointer;
            width: 100%; /* 将宽度设置为100%以与容器对齐 */
            align-self: flex-start; /* 按钮左对齐 */
        }
        
        @media (max-width: 600px) {
            .container {
                flex-wrap: wrap; /* 在屏幕宽度不足时换行显示 */
            }

            .box {
                width: 100%; /* 让框占满一行 */
                margin-bottom: 20px; /* 添加底边距 */
            }
        }
        .image-list {
            display: flex; /* 使用flex布局 */
            flex-wrap: wrap; /* 允许列表换行 */
            justify-content: space-around; /* 间隔均匀分布 */
            align-items: center; /* 垂直居中对齐 */
        }

        .image-list img {
            max-width: 18%; /* 图片最大宽度占比,根据需要调整 */
            margin: 5px; /* 图片之间的间隔 */
            object-fit: contain; /* 确保图片等比例缩放 */
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="box">
            <h2 class="box-title">绘图结果</h2>
            <div id="image-container">
            </div>
        </div>
        <div class="box">
            <h2 class="box-title">文本描述</h2>
            <div id="input-container">
                <textarea id="text-description" title="文本描述" placeholder="文本描述。
算法将根据输入的文本智能生成与之相关的图像。建议详细描述画面主体、细节、场景等,文本描述越丰富,生成效果越精美。
不能为空,推荐使用中文。最多传512个字符。"></textarea>
                <textarea id="text-description2" title="反向文本描述" placeholder="反向文本描述。
用于一定程度上从反面引导模型生成的走向,减少生成结果中出现描述内容的可能,但不能完全杜绝。
推荐使用中文。最多传512个字符。"></textarea>
                <select id="dropdown" title="分辨率">
                  <option value="768:1024">分辨率(默认768:1024)</option>
                  <option value="768:768">768:768</option>
                  <option value="1024:768">1024:768</option>
                </select>
                <select id="dropdown2" title="绘画风格">
                  <option value="201">绘画风格(默认日系动漫风格)</option>
                </select>
                <div style="display: flex; justify-content: flex-start; width: 100%;">
                  <input id="acckey" type="password" placeholder="访问密钥" style="width: 100%;">
               </div>
                <button id="generate-button">生成</button>
            </div>
        </div>
        
    </div>
    <!-- 图片列表容器 -->
    <div class="image-list" id="image-list">
        <!-- 图片将被动态插入到这里 -->
    </div>
    <script>
    // 页面加载完成后执行的函数
        window.onload = function() {
            // 假设您已经有了一个函数来发起请求和处理响应
            // 这里我们直接调用这个函数
            createImageList();
        };
    var ip = "http://101.43.51.133";
  document.getElementById("generate-button").addEventListener("click", function() {
    var Ai_Image_Prompt = document.getElementById("text-description").value;
    var Ai_Image_NegativePrompt = document.getElementById("text-description2").value;
    var Ai_Image_Size = document.getElementById("dropdown").value;
    var Ai_Image_Styles = document.getElementById("dropdown2").value;
    var Ai_Image_AccKey = document.getElementById("acckey").value;


    var data = {
      "denoising_strength": 0,
      "override_settings": {
        "sd_model_checkpoint" :"animagineXLV31_v30.safetensors [1449e5b0b9]"
     }, 
      "prompt": Ai_Image_Prompt,
      "negative_prompt": Ai_Image_NegativePrompt,
      "seed": 0,
      "batch_size": 1,
      "n_iter": 1,
      "num_inference_steps": 28,
      "guidance_scale": 7,
      "sdxl_style": "(None)",
      "quality_tags": "(None)",
      "width": 512,
      "height": 512,
      "sampler": "Euler a"
    };

    var xhr = new XMLHttpRequest();
    xhr.open("POST", ip + "/sdapi/v1/txt2img", true);
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.onreadystatechange = function() {
        if(xhr.readyState === 4){
      if (xhr.status === 200) {
        var response = JSON.parse(xhr.responseText);
          var imageContainer = document.getElementById("image-container"); 
          // 创建一个新的img元素
          var imgElement = document.createElement("img");
          imageContainer.style.backgroundSize = "contain";
            // 设置img元素的src属性为base64编码的图片数据
            imgElement.src = 'data:image/png;base64,'+response.images[0];
            // 设置img元素的alt属性
            imgElement.alt = "动态生成的图片";

            // 将img元素添加到imageContainer中
            imageContainer.appendChild(imgElement);
            // 由于img元素是异步加载的,我们需要等待图片加载完成后再进行操作
      }else{
          alert("请求错误:" + xhr.status);
      }
    }
    };
    xhr.onerror = function() {
        // 处理网络错误
        alert("网络错误");
    };
    xhr.send(JSON.stringify(data));
  });
  // 处理图片列表的函数
    function createImageList() {
        var imageList = document.getElementById("image-list");
        imageList.innerHTML = ""; // 清空当前列表
        // 使用for循环生成图片元素
        for (var i = 1; i <= 5; i++) {
            // 创建新的img元素
            var img = document.createElement("img");
            // 设置图片的src属性为对应的图片文件路径
            // 假设所有图片都存放在同一个目录下
            img.src = "http://ai-zone-2vjn2f1z4giq-1302107156.eo-edgefunctions.com/images/" + i + ".png?ip="+ip;
            img.alt = "Image " + i; // 设置alt属性
            img.style.width = '100%'; // 设置图片宽度为100%

            // 将img元素添加到图片列表容器中
            imageList.appendChild(img);
        }
    }
</script>

</body>
</html>

`;
async function handleRequest(request) {
return new Response(html, {
headers: {
'content-type': 'text/html; charset=UTF-8',
'x-edgefunctions-test': 'Welcome to use Edge Functions.',
},
});
}
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request));
});

这段代码定义了一个HTML页面,用于展示一个AI绘图应用的用户界面,并包含了与之交互的JavaScript代码。主要功能和组成部分如下:

  1. HTML结构
    • 页面包含一个容器container,用于布局两个主要部分:绘图结果展示和文本描述输入。
    • 绘图结果部分包含一个标题和一个图像容器image-container,用于展示AI生成的图像。
    • 文本描述部分包含两个文本区域text-descriptiontext-description2,供用户输入正向描述和反向描述,用于指导AI绘图。
    • 一个按钮generate-button,用于触发AI绘图过程。
  2. JavaScript逻辑
    • 页面加载完成后,调用createImageList函数,动态生成一个图片列表并展示在页面上。
    • 监听generate-button按钮的点击事件,收集用户输入的描述和选择的参数,构造一个AI绘图请求,并发送到服务器。
    • 使用XMLHttpRequest对象发送POST请求到指定的服务器地址,处理响应并动态更新页面上的图像容器以展示生成的图像。

我们看一下最终效果:

实践指南:EdgeOne与HAI的梦幻联动

我已经将 IP 地址单独抽离出来,以确保最小化变动量。如果需要重启,只需更新 IP 地址,然后重新部署即可重新访问。

实践指南:EdgeOne与HAI的梦幻联动

让我们再次观察一下生成图片的效果。点击生成时,后台接口的响应也都是正常的。

实践指南:EdgeOne与HAI的梦幻联动

实践指南:EdgeOne与HAI的梦幻联动

质量确实还有提升空间,我仔细检查了一下,发现问题可能出在模型的限制上。例如,对于宽高比不能是正方形的图像,可以稍微宽一点或高一点。这样生成的图像会更具观赏性。但这些问题都是可以通过调试解决的。总的来说,我们的EdgeOne和HAI的梦幻联动已经取得了阶段性的成果,算是告一段落了。

总结

本篇文章源于他人创意的启发与深入思考,我投入了大量时间与精力,致力于EdgeOne与HAI之间的协同调试,克服了众多技术奇葩问题。通过不懈的努力,成功地将这两个强大的平台整合在一起,打造出一个还不错的参考案例。这次探索也是我个人首次涉足边缘函数式产品的实践之旅。我希望通过分享这次的经历和成果,能够激发更多人对这些前沿技术的兴趣和探索。如果你对我的项目感兴趣,或者从中获得了灵感与帮助,不妨点赞支持,也欢迎关注我,一起交流学习,共同进步。文章来源地址https://www.toymoban.com/news/detail-844573.html

到了这里,关于实践指南:EdgeOne与HAI的梦幻联动的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【腾讯云 HAI域探秘】StableDiffusionWebUI一小时搞定100张设计图

    腾讯云高性能应用服务 HAI 是为开发者量身打造的澎湃算力平台。无需复杂配置,便可享受即开即用的GPU云服务体验。在 HAI 中,根据应用智能匹配并推选出最适合的GPU算力资源,以确保您在数据科学、LLM、AI作画等高性能应用中获得最佳性价比。 本文主要是通过 HAI 部署了

    2024年02月06日
    浏览(39)
  • 腾讯云下一代CDN -- EdgeOne加速MinIO对象存储

    使用MinIO作为EdgeOne的源站。 项目中需要一个兼容S3协议的对象存储服务,腾讯云的COS虽然也兼容S3协议,但是也只是支持简单的上传下载,对于上传的时候同时打标签这种需求,就不兼容S3了。所以决定自建一个对象存储服务,这里选择EdgeOne为对象存储提供CDN加速服务。本文

    2024年02月11日
    浏览(58)
  • 机器学习-搜索技术:从技术发展到应用实战的全面指南

    在本文中,我们全面探讨了人工智能中搜索技术的发展,从基础算法如DFS和BFS,到高级搜索技术如CSP和优化问题的解决方案,进而探索了机器学习与搜索的融合,最后展望了未来的趋势和挑战,提供了对AI搜索技术深刻的理解和展望。 关注TechLead,分享AI全维度知识。作者拥有

    2024年02月05日
    浏览(59)
  • 中国电信移动物联网发展成果与创新实践 ,干货满满

    近日, 首届移动物联网大会(2022) (以下简称“大会”)在江苏省无锡市举办。本次大会由工信部指导,中国信息通信研究院(以下简称“中国信通院”)、中国通信学会、无锡市人民政府、人民邮电报社、江苏省工业和信息化厅、江苏省通信管理局共同主办,无锡物联网

    2024年02月09日
    浏览(41)
  • ChatGPT的快速发展究竟给我们带来了什么?

    😚一个不甘平凡的普通人,致力于为Golang社区和算法学习做出贡献,期待您的关注和认可,陪您一起学习打卡!!!😘😘😘 🤗专栏:算法学习 🤗专栏:Go实战 💬个人主页:个人主页 人工智能(AI)技术在过去几十年中得到了迅速的发展,其中自然语言处理技术的进展更

    2024年02月05日
    浏览(49)
  • Canvas 梦幻树生长动画

    canvas实例应用100+ 专栏提供canvas的基础知识,高级动画,相关应用扩展等信息。 canvas作为html的一部分,是图像图标地图可视化的一个重要的基础,学好了canvas,在其他的一些应用上将会起到非常重要的帮助。 canvas可以制作出非常炫酷的动画,以下是一个梦幻树的示例。 属性

    2024年02月05日
    浏览(44)
  • 传统交换机当今交换机不同之处分析

    目前市场上的某些交换机号称具有QoS保证,实际上只支持单级别的优先级设置,在逻辑上不形成环路,而一旦出现故障,启用备份链路,在这里拿出来和大家分享一下,希望对大家有用。 我们经常说到的以太网传统交换机实际是一个基于网桥技术的多端口第二层网络设备,它

    2024年02月05日
    浏览(43)
  • 在当今信息化社会中的安全大文件传输

    随着科技的不断进步,数据已经成为各个领域和行业的宝贵财富。然而,随之而来的数据传输和交换问题也成为一个日益突出的挑战。在这篇文章中,我们将探讨在当今信息化社会中的安全大文件传输的重要性,以及如何应对传统传输方式所面临的各种挑战。 安全大文件传输

    2024年02月11日
    浏览(45)
  • Web3 治理实践探讨:如何寻找多元化发展路径?

    Web3 领域变革正崭露头角,而社区治理开始成为行业热议话题。 Web3 项目如何探寻多元化建设的解困路径 ,究竟是治理模型的精进成为首要问题,还是吸纳更多资金与组织教育培训,让开发者成为项目建设的中坚力量? 本期 TinTinWeekly 带你寻找这些问题的答案! 10 月 19 日 

    2024年02月08日
    浏览(46)
  • 中国版ChatGPT在哪些方面具有快速发展的机会?

    目录 一、中国巨大的市场需求 二、中国企业加速创新 三、中国的人工智能发展 四、企业愿景的推进 五、科技环境的发展 结语 ChatGPT 是一款由 OpenAI 开发的机器人聊天系统,旨在通过 AI 技术建立起人类与机器之间的自然沟通方式。由于 ChatGPT 在语言理解和生成方面的优秀表

    2023年04月23日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包