基于ernie-gen世界领先文本生成模型的企业公告文本生成


本文围绕企业公告批量生成展开,介绍基于ERNIE-GEN模型的相关尝试。阐述其架构、数据集读取与处理方式,展示训练过程及参数设置,经训练后模型Rouge-1达40.63044、Rouge-2达32.03214,优于T5,可提升职场文案生产效率,还提及模型应用场景与引用信息。

☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜

基于ernie-gen世界领先文本生成模型的企业公告文本生成 -

企业文案场景文本生成尝试

目前阶段的文本生成模型在信息较为固定,存在潜在模版发现的内容分布中存在着较大的商业化场景潜力。 本次项目起源是世界五百强企业的文案小姐姐委托我,为了可以批量化生产企业对外公告的任务展开的。核心应用场景是提升职场文案人的内容生产效率。

2025 流行文本生成模型集合

文本生成大集合,分为预训练文本生成模型,seq2seq文本生成模型,ernie-gen主要是seq2seq的文本生成模型。基于百度开源的ernie模型参数,我们可以很快的获取到一个接近我们需求的方案。

  1. gpt系列
       

很经典的文本生成任务。

  1. unlim系列
       

我最开始接触时因为苏剑林老师的一个文章。有计划用paddle重新实现一个版本。

  1. ernie-gen系列
       

3.1 ernie-gen概述

目前自然语言生成的预训工作对于下游任务的偏差问题关注不够。 为了解决这个问题,我们提出了一个增强的多流序列来排列预训练和微调框架 ERNIE-GEN,它通过生成机制和噪声感知生成方法来弥补训练和推理之间的差异。 为了使代更接近人类的书写模式,该框架引入了一个跨越代流,训练模型连续预测语义完整跨度,而不是逐字预测。ERNIE-GEN与现有的预训练方法不同,它将多粒度目标采样结合到预训练数据中,增强了编解码器之间的相关性。 实验结果表明,ERNIE-GEN 在一系列语言生成任务中,包括抽象概括(Gigaword 和 cnn / dailymail)、问题生成(SQuAD)、对话生成(Persona-Chat)和生成问题回答(CoQA) ,只需要很少的预训练训练数据和参数就可以获得最先进的结果。

3.2 ernie-gen的架构

ERNER-GEN 基于生成机制,采用多流注意体系结构,并行地对模型进行逐字、逐段生成任务的训练。 在本节中,我们根据图2所示的训练过程描述 ERNIE-GEN。

引入我们企业公告生成所需要的一些包。

In [1]
import osimport astimport timeimport argparseimport loggingimport jsonimport paddlefrom tqdm import tqdmimport paddle.nn as nn# 利用paddle io的数据集读取办法会在内存和cpu的运行过程中更加的稳定from paddle.io import DataLoader# 参数我们选用的是ernie gen的参数。令牌器我们可以选择 ErnieTokenizer, ErnieTinyTokenizer, BertTokenizer, \
    # ElectraTokenizer, RobertaTokenizer令牌器 优先推荐ernie tiny令牌器 效果是相对来说比较好的 可以容纳更多的上下文信息from paddlenlp.transformers import ErnieForGeneration, ErnieTokenizer, ErnieTinyTokenizer, BertTokenizer, \
    ElectraTokenizer, RobertaTokenizer, LinearDecayWithWarmupfrom paddlenlp.datasets import load_datasetfrom paddlenlp.data import Stack, Tuple, Padfrom paddlenlp.metrics import Rouge1, Rouge2from paddlenlp.utils.log import loggerfrom encode import convert_example, after_paddingfrom decode import post_process, beam_search_infillingfrom model import StackModel
   

自定义数据集读取。

简小派 简小派

简小派是一款AI原生求职工具,通过简历优化、岗位匹配、项目生成、模拟面试与智能投递,全链路提升求职成功率,帮助普通人更快拿到更好的 offer。

简小派 123 查看详情 简小派 In [2]
def read(data_path):
    count = 0
    f = json.load(open(data_path))    for line in f:                yield {'tokens': "\x02".join(list(line[0])), 'labels': "\x02".join(list(line[1]))}def read_dev(data_path):
    f = json.load(open(data_path))    for line in f:                yield {'tokens': "\x02".join(list(line[0])), 'labels': "\x02".join(list(line[1]))}# 第一个参数我们把读取数据集的方法给穿进去 ,第二个参数是数据集的地址,因为bml存在版本容量上限,这里面我们选用的是一个只包含一万# 段文本生成的数据集map_ds = load_dataset(read, data_path='dataset/max_len_128/train_data_little.json', lazy=False)
dev_ds = load_dataset(read_dev, data_path='dataset/max_len_128/dev_data.json', lazy=False)
   

验证部分我们采用文本生成最常用的rouge-1、rouge-2

In [3]
def evaluate(model, data_loader, tokenizer, rouge1, rouge2, attn_id,
             tgt_type_id):
            
    model.eval()

    vocab = tokenizer.vocab
    eos_id = vocab[tokenizer.sep_token]
    sos_id = vocab[tokenizer.cls_token]
    pad_id = vocab[tokenizer.pad_token]
    unk_id = vocab[tokenizer.unk_token]
    vocab_size = len(vocab)
    evaluated_sentences_ids = []
    reference_sentences_ids = []
    logger.info("Evaluating...")    for data in tqdm(data_loader):
        (src_ids, src_tids, src_pids, _, _, _, _, _, _, _, _,
         raw_tgt_labels) = data  # never use target when infer
        # Use greedy_search_infilling or beam_search_infilling to get predictions
        output_ids = beam_search_infilling(
            model,
            src_ids,
            src_tids,
            eos_id=eos_id,
            sos_id=sos_id,
            attn_id=attn_id,
            pad_id=pad_id,
            unk_id=unk_id,
            vocab_size=vocab_size,
            max_decode_len=max_decode_len,
            max_encode_len=max_encode_len,
            beam_width=beam_width,
            length_penalty=length_penalty,
            tgt_type_id=tgt_type_id)        for ids in output_ids.tolist():            if eos_id in ids:
                ids = ids[:ids.index(eos_id)]
            evaluated_sentences_ids.append(ids)        for ids in raw_tgt_labels.numpy().tolist():
            ids = ids[:ids.index(eos_id)]
            reference_sentences_ids.append(ids)# 计算rouge1 
    score1 = rouge1.score(evaluated_sentences_ids, reference_sentences_ids)# 计算rouge2
    score2 = rouge2.score(evaluated_sentences_ids, reference_sentences_ids)# 日志打印 rouge1 rouge2
    logger.info("Rouge-1: %.5f ,Rouge-2: %.5f" % (score1 * 100, score2 * 100))

    evaluated_sentences = []
    reference_sentences = []    for ids in reference_sentences_ids[:5]:
        reference_sentences.append(''.join(            map(post_process, vocab.to_tokens(ids))))    for ids in evaluated_sentences_ids[:5]:
        evaluated_sentences.append(''.join(            map(post_process, vocab.to_tokens(ids))))
    logger.debug(reference_sentences)
    logger.debug(evaluated_sentences)

    model.train()
    In [4]
def train():
    paddle.set_device(device)    if paddle.distributed.get_world_size() > 1:
        paddle.distributed.init_parallel_env()

    model = ErnieForGeneration.from_pretrained(model_name_or_path)    # 文本特征分割转id的差异
    if "ernie-tiny" in model_name_or_path:
        tokenizer = ErnieTinyTokenizer.from_pretrained(model_name_or_path)    elif "ernie" in model_name_or_path:
        tokenizer = ErnieTokenizer.from_pretrained(model_name_or_path)    elif "roberta" in model_name_or_path or "rbt" in model_name_or_path:
        tokenizer = RobertaTokenizer.from_pretrained(model_name_or_path)    elif "electra" in model_name_or_path:
        tokenizer = ElectraTokenizer.from_pretrained(model_name_or_path)    else:
        tokenizer = BertTokenizer.from_pretrained(model_name_or_path)    if init_checkpoint:
        model_state = paddle.load(init_checkpoint)
        model.set_state_dict(model_state)

    train_dataset, dev_dataset = map_ds, dev_ds
    attn_id = tokenizer.vocab[        '[ATTN]'] if '[ATTN]' in tokenizer.vocab else tokenizer.vocab['[MASK]']
    tgt_type_id = model.sent_emb.weight.shape[0] - 1

    trans_func = convert_example(
        tokenizer=tokenizer,
        attn_id=attn_id,
        tgt_type_id=tgt_type_id,
        max_encode_len=max_encode_len,
        max_decode_len=max_decode_len,
        noise_prob=noise_prob,
        use_random_noice=use_random_noice)

    train_dataset = train_dataset.map(trans_func)
    train_batch_sampler = paddle.io.DistributedBatchSampler(
        train_dataset, batch_size=batch_size, shuffle=True)
    batchify_fn = lambda samples, fn=Tuple(
        Pad(axis=0, pad_val=tokenizer.pad_token_id),  # src_ids
        Pad(axis=0, pad_val=tokenizer.pad_token_id),  # src_pids
        Pad(axis=0, pad_val=tokenizer.pad_token_type_id),  # src_tids
        Pad(axis=0, pad_val=tokenizer.pad_token_id),  # tgt_ids
        Pad(axis=0, pad_val=tokenizer.pad_token_id),  # tgt_pids
        Pad(axis=0, pad_val=tokenizer.pad_token_type_id),  # tgt_tids
        Pad(axis=0, pad_val=tokenizer.pad_token_id),  # attn_ids
        Pad(axis=0, pad_val=tokenizer.pad_token_id),  # tgt_labels
    ): after_padding(fn(samples))
    train_data_loader = DataLoader(
        dataset=train_dataset,
        batch_sampler=train_batch_sampler,
        collate_fn=batchify_fn,
        num_workers=0,
        return_list=True)

    dev_dataset = dev_dataset.map(trans_func)
    dev_data_loader = DataLoader(
        dataset=dev_dataset,
        batch_size=batch_size,
        collate_fn=batchify_fn,
        num_workers=0,
        return_list=True)

    label_num = model.word_emb.weight.shape[0]
    train_model = StackModel(model)    if paddle.distributed.get_world_size() > 1:        # All 'forward' outputs derived from the module parameters using in DataParallel
        # must participate in the calculation of losses and subsequent gradient calculations.
        # So we use StackModel here to make the model only output loss in its 'forward' function.
        train_model = paddle.DataParallel(train_model)

    max_steps = len(train_data_loader) * num_epochs

    lr_scheduler = LinearDecayWithWarmup(learning_rate, max_steps,
                                         warmup_proportion)    # Generate parameter names needed to perform weight decay.
    # All bias and LayerNorm parameters are excluded.
    decay_params = [
        p.name for n, p in model.named_parameters()        if not any(nd in n for nd in ["bias", "norm"])
    ]
    optimizer = paddle.optimizer.AdamW(
        learning_rate=lr_scheduler,
        epsilon=adam_epsilon,
        parameters=model.parameters(),
        weight_decay=weight_decay,
        grad_clip=nn.ClipGradByGlobalNorm(1.0),
        apply_decay_param_fun=lambda x: x in decay_params)

    rouge1 = Rouge1()
    rouge2 = Rouge2()

    global_step = 1
    tic_train = time.time()    for epoch in range(num_epochs):        for step, batch in enumerate(train_data_loader, start=1):
            (src_ids, src_tids, src_pids, tgt_ids, tgt_tids, tgt_pids, attn_ids,
             mask_src_2_src, mask_tgt_2_srctgt, mask_attn_2_srctgtattn,
             tgt_labels, _) = batch            # import pdb; pdb.set_trace()
            if label_smooth > 0.:
                tgt_labels = nn.functional.label_smooth(
                    nn.functional.one_hot(tgt_labels, label_num),
                    epsilon=label_smooth)
            tgt_pos = paddle.nonzero(attn_ids == attn_id)
            loss = train_model(src_ids, src_tids, src_pids, tgt_ids, tgt_tids,
                               tgt_pids, attn_ids, mask_src_2_src,
                               mask_tgt_2_srctgt, mask_attn_2_srctgtattn,
                               tgt_labels, tgt_pos)            if global_step % logging_steps == 0:                if paddle.distributed.get_rank() == 0:
                    logger.info(                        "global step %d, epoch: %d, batch: %d, loss: %f, speed: %.2f step/s, lr: %.3e"
                        % (global_step, epoch, step, loss, logging_steps /
                           (time.time() - tic_train), lr_scheduler.get_lr()))
                tic_train = time.time()

            loss.backward()
            optimizer.step()
            lr_scheduler.step()
            optimizer.clear_grad()            if global_step % s*e_steps == 0 and paddle.distributed.get_rank(
            ) == 0:
                evaluate(model, dev_data_loader, tokenizer, rouge1, rouge2,
                         attn_id, tgt_type_id)
                output_export_dir = os.path.join(output_dir,                                                 "model_%d" % global_step)                if not os.path.exists(output_export_dir):
                    os.makedirs(output_export_dir)
                model_to_s*e = model._layers if isinstance(
                    model, paddle.DataParallel) else model
                model_to_s*e.s*e_pretrained(output_export_dir)
                tokenizer.s*e_pretrained(output_export_dir)
            global_step += 1
   

接下来我们把我们可控的参数传入

In [ ]
if __name__ == "__main__":
    adam_epsilon = 1e-08
    # 批次数量
    batch_size = 48
    # 束宽度
    beam_width = 1
    device = 'gpu'
    label_smooth = 0.0
    # 学习率
    learning_rate = 2e-05
    length_penalty = 1.0
    # 日志条数
    logging_steps = 1000
    # 输入最大长度
    max_decode_len = 64
    # 输出最大长度
    max_encode_len = 64
    # 基础版本模型选型
    model_name_or_path = 'ernie-1.0'
    noise_prob = 0.0
    num_epochs = 12
    # 模型文件输出地址
    output_dir = './tmp_max_encode_len_64/'
    s*e_dir = None
    # 多少步保存一次模型
    s*e_steps = 3000
    # 使用随机噪声
    use_random_noice = False
    # 激活层比例
    warmup_proportion = 0.1
    weight_decay = 0.1
    init_checkpoint =  None
    train()
       
[2025-12-01 09:41:52,783] [    INFO] - Downloading https://paddlenlp.bj.bcebos.com/models/transformers/ernie/ernie_v1_chn_base.pdparams and s*ed to /home/aistudio/.paddlenlp/models/ernie-1.0
100%|██████████| 392507/392507 [00:06<00:00, 62303.88it/s]
[2025-12-01 09:41:59,167] [   DEBUG] - init ErnieModel with config: {'attention_probs_dropout_prob': 0.1, 'hidden_act': 'relu', 'hidden_dropout_prob': 0.1, 'hidden_size': 768, 'initializer_range': 0.02, 'max_position_embeddings': 513, 'num_attention_heads': 12, 'num_hidden_layers': 12, 'type_vocab_size': 2, 'vocab_size': 18000, 'pad_token_id': 0}
W1201 09:41:59.170681   254 device_context.cc:404] Please NOTE: device: 0, GPU Compute Capability: 7.0, Driver API Version: 10.1, Runtime API Version: 10.1
W1201 09:41:59.176012   254 device_context.cc:422] device: 0, cuDNN Version: 7.6.
[2025-12-01 09:42:05,152] [    INFO] - loading pretrained model from /home/aistudio/.paddlenlp/models/ernie-1.0/ernie_v1_chn_base.pdparams
[2025-12-01 09:42:05,908] [    INFO] - param:mlm_bias not set in pretrained model, skip
[2025-12-01 09:42:05,911] [    INFO] - param:mlm.weight not set in pretrained model, skip
[2025-12-01 09:42:05,912] [    INFO] - param:mlm.bias not set in pretrained model, skip
[2025-12-01 09:42:05,914] [    INFO] - param:mlm_ln.weight not set in pretrained model, skip
[2025-12-01 09:42:05,916] [    INFO] - param:mlm_ln.bias not set in pretrained model, skip
[2025-12-01 09:42:06,233] [    INFO] - Downloading vocab.txt from https://paddlenlp.bj.bcebos.com/models/transformers/ernie/vocab.txt
100%|██████████| 90/90 [00:00<00:00, 2471.55it/s]
[2025-12-01 09:52:35,371] [    INFO] - global step 1000, epoch: 0, batch: 1000, loss: 25.130060, speed: 1.59 step/s, lr: 2.458e-07
[2025-12-01 10:03:07,710] [    INFO] - global step 2000, epoch: 0, batch: 2000, loss: 13.533076, speed: 1.58 step/s, lr: 4.918e-07
[2025-12-01 10:13:37,752] [    INFO] - global step 3000, epoch: 0, batch: 3000, loss: 10.812221, speed: 1.59 step/s, lr: 7.378e-07
[2025-12-01 10:13:38,133] [    INFO] - Evaluating...
100%|██████████| 21/21 [01:24<00:00,  4.04s/it]
[2025-12-01 10:15:03,111] [    INFO] - Rouge-1: 0.63044 ,Rouge-2: 0.03214
[2025-12-01 10:15:03,114] [   DEBUG] - ['书,确认整的,不师行业公事项出具法资料,且公的有关本期资料(包括是完整的、隐瞒、遗漏正本或yuan件的签署人业计划的法律律专业事项', '整的,不师行业公事项出具法资料,且公的有关本期资料(包括是完整的、隐瞒、遗漏正本或yuan件的签署人业计划的法律律专业事项存在虚假', '师行业公事项出具法资料,且公的有关本期资料(包括是完整的、隐瞒、遗漏正本或yuan件的签署人业计划的法律律专业事项存在虚假记作为公', '事项出具法资料,且公的有关本期资料(包括是完整的、隐瞒、遗漏正本或yuan件的签署人业计划的法律律专业事项存在虚假记作为公司实见书', '资料,且公的有关本期资料(包括是完整的、隐瞒、遗漏正本或yuan件的签署人业计划的法律律专业事项存在虚假记作为公司实见书承担相本期']
[2025-12-01 10:15:03,116] [   DEBUG] - [';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;', ';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;', ';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;', ';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;《;;;;;;;;;;;', ';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;']
       

总结

经过漫长的训练,我们最终得到的

Rouge-1: 40.63044 ,Rouge-2: 32.03214

对标的t5的结果是

Rouge-1: 35.92264, Rouge-2: 20.50868

可以看出在目前的数据集中ernie-gen的生成效果是超出t5的效果的。在国际文本生成榜单中ernie-gen也是属于非常名列前茅的文本生成方案。大家快在自己的数据集上面试试效果吧。

应用场景

通过我们的模型可以给一段文本生成下文的模型,可以在用户写到一半的时候通过点点点的方式生成更多的样本。百度paddlenlp再一次验证了一种领先于时代的技术储备的重要性,也体现了百度的开源精神是支撑百度坚守的初心。

以前不知道,要是拿别人的代码写东西出来一定要记得下面这种内容哟。

@article{xiao2025ernie-gen,
  title={ERNIE-GEN: An Enhanced Multi-Flow Pre-training and Fine-tuning Framework for Natural Language Generation},
  author={Xiao, Dongling and Zhang, Han and Li, Yukun and Sun, Yu and Tian, Hao and Wu, Hua and Wang, Haifeng},  journal={arXiv preprint arXiv:2001.11314},
  year={2025}
}
   

以上就是基于ernie-gen世界领先文本生成模型的企业公告文本生成的详细内容,更多请关注其它相关文章!


# 牌器  # 石嘴山网站优化  # sem seo公司  # 山西抖音seo方法  # 江油集团网站建设维护  # 网站优化做得好的标志  # 大连最好的seo专业  # 大冶微信推广网站  # 荣昌机械网站建设费用  # 毛巾推广营销方案怎么写  # 胖哥网络营销推广  # 自己的  # 来袭  # 营收  # 开源  # ai  # 化生  # 职场  # 中文网  # 的是  # 本期  # type  # fig  # gling  # n世界  # udio  # red  # 排列  # 百度 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894


相关推荐: 小米创始人雷军将揭示小米AI在年度演讲中的最新进展  调研海尔智家:AI名,家电命?  《共同的演化》展览启幕,重新思考人类与人工智能关系  讯飞星火大模型实现升级 助力通用人工智能人才培养  普林斯顿Infinigen矩阵开启!AI造物主100%创造大自然,逼真到炸裂  三星加速AR眼镜进程,预计明年上半年亮相  中国最强AI研究院的大模型为何迟到了  英媒:硅谷有些人太鼓吹AI,宣扬“学习无用”  消息称 Meta Quest 将推 VR 游戏订阅:每月 7.99 美元,任选两款  行业首发「超级智绘」AI故事集,TCL实业推进AI技术应用  掌阅科技申请阅爱聊商标 掌阅科技申请AI相关商标  AI新视野,增长新势能,伙伴云受邀出席笔记侠创业讲真话AI峰会  十个AI算法常用库J*a版  机智云AI离线语音识别模组,让家电变得更加智能便捷  1分钟做出苹果Vision Pro「官网」?上班8小时搞出480个网页,同事被卷疯了  换流站无线物联网络为新型电力系统铺设“数字之路”  复旦发布「新闻推荐生态系统模拟器」SimuLine:单机支持万名读者、千名创作者、100+轮次推荐  “上海市民营企业人工智能赋能创新中心”揭牌成立  智能公司为何纷纷投身机器人领域?  谷歌将使用公开信息训练 AI 模型,构建更强大的自家产品  IBM与NASA联手开源地理空间AI基础模型,促进气候科学领域进步  WHEE安装教程  AI绘画,还需要懂数学?  本届人工智能大会上的这个“镇馆之宝”,来自长宁企业西井科技!  亚马逊确认今年不会举办 re:MARS 机器人和人工智能大会  给小朋友最好的科技礼物:乐天派桌面机器人  ​布局智能物联新时代,中国移动“5G+物联网”亮相2025 MWC  比尔盖茨:AI确实存在风险,但可控  “可用”“有用”的讯飞星火认知大模型将亮相世界人工智能大会  家电行业观察:AI加持下,全屋智能将成为智能家电未来?  WAIC 2025|云深处科技绝影Lite3与X20四足机器人亮相  原小米 9 号员工李明打造全球首款 AI 安卓桌面机器人  网易云音乐内测上线“私人DJ” 打造AI推荐音乐助手  人工智能在项目管理中的作用  元宇宙迈入2.0时代,它和生成式人工智能有何关联吗?  一文看懂基础模型的定义和工作原理  AI生成新闻网站数量激增,正在疯狂赚取广告收入  即将到来:AI婚纱设计软件实际测试,人工智能即将开创婚纱设计新纪元  尼康尼克尔Z 180-600mm f/5.6-6.3 VR镜头发布:12499元 拍鸟神器  普林斯顿大学推出Infinigen AI模型 可生成真实自然环境 3D场景  昆仑万维与全球领先的元宇宙公司Meta达成商务合作,共同认可昆仑万维在XR领域的技术实力  美图第二届影像节发布七款AI影像创作工具  商汤科技:元萝卜 AI 下棋机器人新品发布会 6 月 14 日举行  扎克伯格吐槽苹果Vision Pro:社交落后Meta太多,无法建设元宇宙  陈丹琦ACL学术报告来了!详解大模型「*」数据库7大方向3大挑战,3小时干货满满  有远见!华为四年前注册商标Vision Pro:苹果AR国内要改名  Adobe旗下Illustrator引入生成式AI工具Firefly  Bing 聊天机器人现支持在桌面端用语音提问  利亚德加码AI战略,与光年无限图灵机器人全面开展AI研发业务合作  出门问问亮相2025世界人工智能大会,展示AI CoPilot解决方案 

 2025-07-29

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.