/ Steve 心得 / 68浏览

AzureOpenAI

前言

Azure

昨天根据 Azure OpenAI Service 注册申请与配置心得 这篇 Blog 成功注册了 Azure OpenAI Service 。

注册过程大家看上面👆的 Blog 文章就好,这里我仅仅就我踩过的坑来做个说明。

⚠️注意

  1. Azure OpenAI Service 目前需要以企业的身份来申请试用。

    Azure OpenAI Service 接受来自中国的企业申请,请依照表单如实填写信息,其中最重要的是:

    Your Company Email Address:请填写你在你公司的企业邮箱地址。

    经过我的试验使用自定义域名结尾的邮箱可以作为申请,使用个人邮箱如 gmail/hotmail/QQ/outlook 等。基本都是不给过的。

    Company Website:请填写你所在公司的网站的网址。网址里最好能展示一个与你企业邮箱地址同一个域名的邮箱地址。**你的企业邮箱的域名、公司网站的域名需要保持一致,域名的主体需要与公司的名称保持一致,否则会在审核时被拒绝。**

  2. 在使用 Cloudflare 转换 Azure OpenAI Service API 时需要使用 cf-openai-azure-proxy 这个项目。

    其中

    • 直接修改他们的值, 如:

    修改代码值

    注意以上修改代码值的时候请务必加上 ' ' 我一开始没加,一直报错。

    或者通过 cloudflare worker 控制台, 进入 Workers script > Settings > Add variable under Environment Variables.

    cloudflare

    附上完整代码:

    // The name of your Azure OpenAI Resource.
    const resourceName=RESOURCE_NAME
    
    // The deployment name you chose when you deployed the model.
    const mapper = {
     'gpt-3.5-turbo': DEPLOY_NAME_GPT35,
     'gpt-4': DEPLOY_NAME_GPT4
    };
    
    const apiVersion=2023-05-15
    
    addEventListener(fetch, (event) => {
    event.respondWith(handleRequest(event.request));
    });
    
    async function handleRequest(request) {
    if (request.method === 'OPTIONS') {
     return handleOPTIONS(request)
    }
    
    const url = new URL(request.url);
    if (url.pathname === '/v1/chat/completions') {
     var path=chat/completions
    } else if (url.pathname === '/v1/completions') {
     var path=completions
    } else if (url.pathname === '/v1/models') {
     return handleModels(request)
    } else {
     return new Response('404 Not Found', { status: 404 })
    }
    
    let body;
    if (request.method === 'POST') {
     body = await request.json();
    }
    
    const modelName = body?.model;  
    const deployName = mapper[modelName] || '' 
    
    if (deployName === '') {
     return new Response('Missing model mapper', {
         status: 403
     });
    }
    const fetchAPI = <code>https://${resourceName}.openai.azure.com/openai/deployments/${deployName}/${path}?api-version=${apiVersion}</code>
    
    const authKey = request.headers.get('Authorization');
    if (!authKey) {
     return new Response(Not allowed, {
       status: 403
     });
    }
    
    const payload = {
     method: request.method,
     headers: {
       Content-Type: application/json,
       api-key: authKey.replace('Bearer ', ''),
     },
     body: typeof body === 'object' ? JSON.stringify(body) : '{}',
    };
    
    let response = await fetch(fetchAPI, payload);
    response = new Response(response.body, response);
    response.headers.set(Access-Control-Allow-Origin, *);
    
    if (body?.stream != true){
     return response
    } 
    
    let { readable, writable } = new TransformStream()
    stream(response.body, writable);
    return new Response(readable, response);
    
    }
    
    function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
    }
    
    // support printer mode and add newline
    async function stream(readable, writable) {
    const reader = readable.getReader();
    const writer = writable.getWriter();
    
    // const decoder = new TextDecoder();
    const encoder = new TextEncoder();
    const decoder = new TextDecoder();
    // let decodedValue = decoder.decode(value);
    const newline = n;
    const delimiter = nn
    const encodedNewline = encoder.encode(newline);
    
    let buffer = ;
    while (true) {
     let { value, done } = await reader.read();
     if (done) {
       break;
     }
     buffer += decoder.decode(value, { stream: true }); // stream: true is important here,fix the bug of incomplete line
     let lines = buffer.split(delimiter);
    
     // Loop through all but the last line, which may be incomplete.
     for (let i = 0; i < lines.length - 1; i++) {
       await writer.write(encoder.encode(lines[i] + delimiter));
       await sleep(20);
     }
    
     buffer = lines[lines.length - 1];
    }
    
    if (buffer) {
     await writer.write(encoder.encode(buffer));
    }
    await writer.write(encodedNewline)
    await writer.close();
    }
    
    async function handleModels(request) {
    const data = {
     object: list,
     data: []  
    };
    
    for (let key in mapper) {
     data.data.push({
       id: key,
       object: model,
       created: 1677610602,
       owned_by: openai,
       permission: [{
         id: modelperm-M56FXnG1AsIr3SXq8BYPvXJA,
         object: model_permission,
         created: 1679602088,
         allow_create_engine: false,
         allow_sampling: true,
         allow_logprobs: true,
         allow_search_indices: false,
         allow_view: true,
         allow_fine_tuning: false,
         organization: *,
         group: null,
         is_blocking: false
       }],
       root: key,
       parent: null
     });  
    }
    
    const json = JSON.stringify(data, null, 2);
    return new Response(json, {
     headers: { 'Content-Type': 'application/json' },
    });
    }
    
    async function handleOPTIONS(request) {
     return new Response(null, {
       headers: {
         'Access-Control-Allow-Origin': '*',
         'Access-Control-Allow-Methods': '*',
         'Access-Control-Allow-Headers': '*'
       }
     })
    }
    

最后

如果你成功做完了所有的步骤。那么你应该有一个可以取代 OpenAI API 功能的密钥以及 Cloudflare WorkerURL 链接了。

使用方法如下:

  • 请在设置中选择OpenAI作为Default Service Provider
  • API KEY:请填写Azure OpenAI Service密钥
  • API URL:请填写Cloudflare Worker的 URL。
  • API Model 选择你已部署的 Model,例如gpt-35-turbo (version 0301),而这个Model需要你在Cloudflare Worker代码最前面的 mapper 中做好映射。
Steve
Follow
国行 iPhone 16 系列开启 Apple Intelligence 保姆级教程
国行 iPhone 16 系列开启 Apple Intelligence 保姆级教程
船新版本的 Surge 配置- 支持 Apple Intelligence 分流已更新
船新版本的 Surge 配置- 支持 Apple Intelligence 分流已更新
2024-砥砺前行
2024-砥砺前行
美区 Apple ID 注册教程
美区 Apple ID 注册教程
Debian 12 / Ubuntu 22.04 安装 Docker 以及 Docker Compose 教程
Debian 12 / Ubuntu 22.04 安装 Docker 以及 Docker Compose 教程

0

  1. This post has no comment yet

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注