Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >react-grid-layout 之核心代码分析与实践

react-grid-layout 之核心代码分析与实践

作者头像
政采云前端团队
发布于 2023-10-16 12:40:57
发布于 2023-10-16 12:40:57
2.6K00
代码可运行
举报
文章被收录于专栏:采云轩采云轩
运行总次数:0
代码可运行

1. 介绍

React Grid Layout 是一个用于构建可拖拽、可调整大小和自适应的网格布局的 React 组件库。通过简单易用的API,在 React 项目中能够快速构建复杂网格布局,轻松地创建可交互的网格布局,适用于构建面向用户的仪表盘、拖拽式页面布局等应用,提供良好的交互体验。通常用于自定义搭建页面中,例如我们公司用到自定义搭建工作台系统等等

React Grid Layou组件库的特点有:可拖拽、可调整大小,适应不同需求、自动适应支持响应式断点、设置组件的对齐方式和间距、支持自定义的组件和布局等等

本篇文章将带你了解如何使用 RGL(React Grid Layout),以及核心功能断点布局、网格布局、以及缩放、拖拽功能的代码实现。

2. 使用

下载 npm 包

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
npm install react-grid-layout

引入 RGL(react-grid-layout)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import GridLayout from "react-grid-layout";

设置初始化布局

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 布局属性
const layout = [
  // i: 组件key值, x: 组件在x轴的坐标, y: 组件在y轴的坐标, w: 组件宽度, h: 组件高度
  // static: true,代表组件不能拖动
  { i: "a", x: 0, y: 0, w: 1, h: 3, static: true },  
  // minW/maxW 组件可以缩放的最大最小宽度
  { i: "b", x: 1, y: 0, w: 3, h: 2, minW: 2, maxW: 4 }, 
  { i: "c", x: 4, y: 0, w: 1, h: 2 }
];

return (
  <GridLayout
    className="layout"
    layout={layout} // 组件的布局参数配置
    cols={12} // 栅格列数配置,默认12列
    rowHeight={30} // 指定网格布局中每一行的高度, 这里设置为30px
    width={1200} // 设置容器的初始宽度
  >
    <div key="a" >组件A</div>
    <div key="b" >组件B</div>
    <div key="c" >组件C</div>
  </GridLayout>
)

效果图

3. 源码实现

3.1 断点布局实现

首先我们要了解什么是断点布局?

断点布局(Breakpoint layout)是一种响应式布局的设计方法,用于在不同的屏幕尺寸的显示和布局。

断点布局和网格布局不同点在于,断点布局需要根据不同屏幕大小的断点来设置不同的布局,例如下面代码,定义 lg、md、sm、xs 四个断点 ,并设置每一个断点对应的列数和布局。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const MyGrid = () => {
  // 定义断点
  const breakpoints = { lg: 1200, md: 996, sm: 768, xs: 480 }; 
  // 定义断点对应的列数
  const cols = { lg: 12, md: 10, sm: 6, xs: 4 };

  // 定义不同断点下的布局
  const layouts = {
    lg: [
      { i: 'a', x: 0, y: 0, w: 6, h: 3 },
      { i: 'b', x: 6, y: 0, w: 6, h: 3 },
    ],
    md: [
      { i: 'a', x: 0, y: 0, w: 5, h: 3 },
      { i: 'b', x: 5, y: 0, w: 5, h: 3 },
    ],
    sm: [
      { i: 'a', x: 0, y: 0, w: 6, h: 3 },
      { i: 'b', x: 0, y: 3, w: 6, h: 3 },
    ],
    xs: [
      { i: 'a', x: 0, y: 0, w: 4, h: 3 },
      { i: 'b', x: 0, y: 3, w: 4, h: 3 },
    ],
  };

  return ( 
    <ResponsiveReactGridLayout 
      className="layout" 
      breakpoints={breakpoints} 
      cols={cols} 
      layouts={layouts} 
    > 
      <div key="a">Component A</div> 
      <div key="b">Component B</div>
    </ResponsiveReactGridLayout>
  );
};

断点布局实现的关键是获取并监听屏幕宽度的变化,这里使用了 resize-observer-polyfill 组件库,可以兼容旧浏览器实现元素大小的变化。首先我们创建一个 ResizeObserver 实例,在回调函数中获取目标元素的宽度,并通过 setState 更新。下面是获取屏幕宽度的主要代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import ResizeObserver from 'resize-observer-polyfill';// 引入resize-observer-polyfill

this.resizeObserver = new ResizeObserver((entries) => {

  const node = this.elementRef.current // 获取当前元素节点

  if (node instanceof HTMLElement) {

    // 通过 resize-observer-polyfill 中的 api 获取当前元素的宽度
    const width = entries[0].contentRect.width 
    this.setState({width})
    
  }

})

现在我们知道了如何获取元素的宽度,当我们缩放视图窗口时,需要判断目前视图窗口的宽度处于哪个断点范围内,这时候我们用到的方法是 onWidthChange,该方法会监听每一次宽度变化,根据新的窗口宽度和断点信息,重新计算网格布局,并更新组件状态。其中 getBreakpointFromWidth 方法根据当前屏幕宽度,返回设置的断点。getColsFromBreakpoint 方法根据断点,返回当前的布局。下面的核心代码实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 判断断点是否变化
if (
  lastBreakpoint !== newBreakpoint ||
  prevProps.breakpoints !== breakpoints ||
  prevProps.cols !== cols
) {
  // 如果下一个布局中没有当前断点,则保留当前布局
  if (!(lastBreakpoint in newLayouts))
    newLayouts[lastBreakpoint] = cloneLayout(this.state.layout);

  // 根据现有布局和新的断点查找或生成布局
  let layout = findOrGenerateResponsiveLayout(
    newLayouts,
    breakpoints,
    newBreakpoint,
    lastBreakpoint,
    newCols,
    compactType
  );

  // 根据子元素和初始布局生成新的布局
  layout = synchronizeLayoutWithChildren(
    layout,
    this.props.children,
    newCols,
    compactType,
    this.props.allowOverlap
  );

  // 存储新布局。
  newLayouts[newBreakpoint] = layout;

  this.setState({
    breakpoint: newBreakpoint,
    layout: layout,
    cols: newCols
  }); // 存入当前新的断点数据
}

插入:这里我们是使用了 resize-observer-polyfill 组件库中的 api 来监听屏幕宽高变化,我们还可以使用 css 中的 @media 来实现宽高变化带来的样式改变。另外还有 js 的原生方法 window.innerWidth 获取屏幕的宽高并通过 window.addEventListener 监听宽度的变化。

3.2 网格布局实现

什么是网格布局?

网格布局是一种用于创建网格化布局的 CSS 布局模块。它允许开发者将一个元素的内容划分为行和列,形成一个灵活且强大的布局系统。

在 RGL(React Grid Layout)中,创建一个网络布局做了三件事:

1、渲染子组件 child,包括子组件元素的定位、占比、宽高等

2、合并类名和样式

3、绑定缩放和拖拽事件

根据设置的 x,y 坐标计算子组件到顶部和左边的距离分别为 left,top,和子组件的宽度和高度。温馨提示,在后面的代码实现过程中会有许多 x,y 和 left,top 的转换,下面的这张图方便我们理解:

实现代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
render(): ReactNode {
  const {
    x,
    y,
    w,
    h,
    isDraggable,
    isResizable,
    droppingPosition,
    useCSSTransforms
  } = this.props;

  // 定位
  const pos = calcGridItemPosition(
    this.getPositionParams(),
    x,
    y,
    w,
    h,
    this.state
  );
  const child = React.Children.only(this.props.children);

  // 创建子元素。我们克隆现有的元素,但修改它的className和样式。
  let newChild = React.cloneElement(child, {
    ref: this.elementRef,
    className: clsx(
      "react-grid-item",
      child.props.className,
      this.props.className,
      {
        static: this.props.static,
        resizing: Boolean(this.state.resizing),
        "react-draggable": isDraggable,
        "react-draggable-dragging": Boolean(this.state.dragging),
        dropping: Boolean(droppingPosition),
        cssTransforms: useCSSTransforms
      }
    ),
    // 我们可以设置子元素的宽度和高度,但我们不能设置位置。
    style: {
      ...this.props.style,
      ...child.props.style,
      ...this.createStyle(pos)
    }
  });

  // 绑定缩放事件
  newChild = this.mixinResizable(newChild, pos, isResizable);

  // 绑定拖拽事件
  newChild = this.mixinDraggable(newChild, isDraggable);

  return newChild;
}

子组件渲染

通过 children.map 遍历执行 processGridItem 方法,在 processGridItem 方法中将每一个 child 的 key 作为 id 设置布局项并且把要设置的布局属性和回调函数传递到 组件。

calcGridItemPosition - 定位

当我们要知道子组件的定位时,需要计算子组件到顶部和左边的距离和子组件的宽高,实现代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export function calcGridItemPosition() {
  const { margin, containerPadding, rowHeight } = positionParams;
  const colWidth = calcGridColWidth(positionParams);
  const out = {};

  // 缩放态计算宽高
  if (state && state.resizing) {
    out.width = Math.round(state.resizing.width);
    out.height = Math.round(state.resizing.height);
  }
  // 否则,按网格单位计算。
  else {
    out.width = calcGridItemWHPx(w, colWidth, margin[0]);
    out.height = calcGridItemWHPx(h, rowHeight, margin[1]);
  }

  // 拖动态计算top、left
  if (state && state.dragging) {
    out.top = Math.round(state.dragging.top);
    out.left = Math.round(state.dragging.left);
  }
  // 否则,按网格单位计算。
  else {
    out.top = Math.round((rowHeight + margin[1]) * y + containerPadding[1]);
    out.left = Math.round((colWidth + margin[0]) * x + containerPadding[0]);
  }

  return out;
}

在上面的代码中,我们看到在网格单位计算中用到了 calcGridColWidth、calcGridItemWHPx 方法, calcGridColWidth 用于计算每一列的宽度,calcGridItemWHPx 用于计算整个网络布局的宽高。下面分别详细介绍:

计算每一列的宽度

根据 positionParams 属性中的 margin, containerPadding, containerWidth, cols 等,计算网格中每一列的宽度:

容器宽度-所有列的内、外边距)/列数

如下图所示:

calcGridColWidth 方法代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export function calcGridColWidth(positionParams: PositionParams): number {
  const { margin, containerPadding, containerWidth, cols } = positionParams;
  return (
    (containerWidth - margin[0] * (cols - 1) - containerPadding[0] * 2) / cols
  );
}
计算网格项目宽高

网格项目的大小 = 所有子组件 child 实际占的大小 + 子组件 child 之间的边距大小

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
export function calcGridItemWHPx(
  // 子组件 child 的宽或高 w/h
  gridUnits: number, 
  // 每个网格单位在像素上实际的大小,也就是上面 calcGridColWidth 计算的每一列宽度
  colOrRowSize: number, 
  // 子组件 child 之间的间距
  marginPx: number
): number {
  // 0 * Infinity === NaN, which causes problems with resize contraints
  if (!Number.isFinite(gridUnits)) return gridUnits;
  return Math.round(
    colOrRowSize * gridUnits + Math.max(0, gridUnits - 1) * marginPx
  );
}

合并样式

克隆当前的子组件 child 合并 className 和样式,合并类名使用了 clsx。clsx 是一个用于动态生成 CSS 类名的工具,使得合并和处理类名变得更加简单和灵活。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const child = React.Children.only(this.props.children);

// 通过克隆现有的元素创建为新的子元素,并修改它的 className 和样式。
let newChild = React.cloneElement(child, {
  ref: this.elementRef,
  className: clsx(
    "react-grid-item",
    child.props.className,
    this.props.className,
    {
      static: this.props.static,
      resizing: Boolean(this.state.resizing),
      "react-draggable": isDraggable,
      "react-draggable-dragging": Boolean(this.state.dragging),
      dropping: Boolean(droppingPosition),
      cssTransforms: useCSSTransforms
    }
  ),
  // 我们可以设置子元素的宽度和高度
  style: {
    ...this.props.style,
    ...child.props.style,
    ...this.createStyle(pos)
  }
});

// 绑定缩放功能。默认是可缩放,用户也可设置为不可缩放
newChild = this.mixinResizable(newChild, pos, isResizable);

// 绑定拖拽功能。默认是可拖拽,用户也可设置为不可拖拽
newChild = this.mixinDraggable(newChild, isDraggable);

在上面这段代码中,我们克隆后的新元素都调用 mixinResizable、mixinDraggable 方法,分别用来执行可缩放和拖拽功能的。下面具体讲讲如何实现

3.3 拖拽功能实现

拖拽功能函数 mixinDraggable,核心用到了 react-draggable 拖拽组件。在 DraggableCore 组件中传入的属性主要有 onDragStart、onDrag、onDragStop 事件等等,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mixinDraggable(
  child: ReactElement<any>,
  isDraggable: boolean
): ReactElement<any> {
  return (
    <DraggableCore
      disabled={!isDraggable} // 是否支持拖拽
      onStart={this.onDragStart} // 开始拖拽触发的事件
      onDrag={this.onDrag} // 拖拽过程中一直触发的事件
      onStop={this.onDragStop} // 拖拽结束时触发的事件
      handle={this.props.handle} // 上一级组件传入的回调函数
      cancel={
        ".react-resizable-handle" +
        (this.props.cancel ? "," + this.props.cancel : "")
      }
      scale={this.props.transformScale}
      nodeRef={this.elementRef}
    >
      {child}
    </DraggableCore>
  );
}

onDragStart - 开始拖拽

在开始拖拽事件中,做了以下事情:

  • 获取当前拖拽元素
  • 获取最近祖先元素中含有定位属性元素
  • 获取以上两种元素的定位信息

首先如何获取当前拖拽元素?在 DraggableCore 组件中的回调函数提供了一个包含拖拽事件相关信息的回调数据对象叫作 ReactDraggableCallbackData,里面的属性包含当前被拖拽的元素节点 node。

第二步如何获取最近祖先元素中含有定位属性元素?在原生 js 中有个 HTMLElement.offsetParent 属性,通过 node.offsetParent 可以获取父级含有定位属性元素

最后通过 DOM 方法中的 getBoundingClientRect 分别获取它们的定位信息对当前元素计算最新定位

具体代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
onDragStart: (Event, ReactDraggableCallbackData) => void = (e, { node }) => {
  const { onDragStart, transformScale } = this.props;
  if (!onDragStart) return;

  const newPosition: PartialPosition = { top: 0, left: 0 };

  // offsetParent: 获取指定元素的最近的祖先元素中含有定位属性(position 不为 static)的元素。
  const { offsetParent } = node;
  if (!offsetParent) return;
  
  // getBoundingClientRect: 获取指定元素的大小和位置信息
  const parentRect = offsetParent.getBoundingClientRect();
  const clientRect = node.getBoundingClientRect();
  const cLeft = clientRect.left / transformScale;
  const pLeft = parentRect.left / transformScale;
  const cTop = clientRect.top / transformScale;
  const pTop = parentRect.top / transformScale;
  newPosition.left = cLeft - pLeft + offsetParent.scrollLeft;
  newPosition.top = cTop - pTop + offsetParent.scrollTop;
  this.setState({ dragging: newPosition }); // 当前拖拽元素最新定位信息

  const { x, y } = calcXY(
    this.getPositionParams(),
    newPosition.top,
    newPosition.left,
    this.props.w,
    this.props.h
  );

  return onDragStart.call(this, this.props.i, x, y, {
    e,
    node,
    newPosition
  });
};

onDrag - 拖拽中

在拖拽的过程中,为了确保元素不超出边界,我们要实时计算拖拽元素是否超出网格,通过计算底部边界 - bottomBoundary 确保元素不会超出其偏移父元素的底部边界;通过计算右侧边界 - rightBoundary 确保元素不会超出其偏移父元素的右侧边界。具体计算步骤如下:

  • 计算底部边界 bottomBoundary:偏移父元素的可见高度减去元素的高度、上下边距之和
  • 计算右侧边界 rightBoundary:容器的宽度减去元素的宽度、左右边距之和
  • 通过 clamp 函数计算将 top、left 的值限制在 0-bottomBoundary、0-rightBoundary

主要代码实现如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
onDrag = () => {
  ...
  const positionParams = this.getPositionParams();

  // 边界计算; 保证项目在网格保持在网格内
  if (isBounded) {
    const { offsetParent } = node;

    if (offsetParent) {
      const { margin, rowHeight } = this.props;
      const bottomBoundary =
        offsetParent.clientHeight - calcGridItemWHPx(h, rowHeight, margin[1]);
      // 将 top 的值设置在 0 到 bottomBoundary 之间
      top = clamp(top, 0, bottomBoundary); 

      const colWidth = calcGridColWidth(positionParams);
      const rightBoundary =
        containerWidth - calcGridItemWHPx(w, colWidth, margin[0]);
      left = clamp(left, 0, rightBoundary);
    }
  }

 ...
}

// utils.js
export function clamp(
num: number,
lowerBound: number,
upperBound: number
): number {
  return Math.max(Math.min(num, upperBound), lowerBound);
}

onDragStop - 拖拽结束

记录下拖拽后新位置,把拖拽计算的 top、left 等定位信息通过 calcXY 函数计算新的位置为 x,y 并保存下来。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
onDragStop: (Event, ReactDraggableCallbackData) => void = (e, { node }) => {
  ...
  const newPosition: PartialPosition = { top, left };
  this.setState({ dragging: null }); // 表示拖拽结束

  const { x, y } = calcXY(this.getPositionParams(), top, left, w, h);

  return onDragStop.call(this, i, x, y, {
    e,
    node,
    newPosition
  });
};

拖拽过程中的阴影是如何实现?

在实际使用拖拽功能时,会有当前拖动元素的阴影站位,如下图11号元素:

如何实现拖拽过程中的阴影?

在我们使用 GRL 渲染子元素时可以添加拖动时的类名例如.droppable-element,并给类目设置样式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
.droppable-element {

  ...

  background: #fdd;
}

此外我们回顾一下上面子组件渲染的时候,有一个合并样式,其中合并 className 里有一项是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"react-draggable-dragging": Boolean(this.state.dragging)

// .css
.react-grid-item.react-draggable-dragging {
  transition: none; // 取消了被拖拽元素上的过渡效果。RGL 默认会添加过渡动画效果来实现平滑的移动效果
  z-index: 3; // 保证拖拽元素在顶部,不被其他元素覆盖
  will-change: transform; // 提示浏览器被拖拽元素将要发生的变化,可以优化动画性能
}

3.4 缩放功能实现

缩放功能需要计算约束缩放的最大最小宽高,并且在可缩放功能用到了 react-resizable 组件。在 Resizable 组件中 传入 minConstraints、maxConstraints 可缩放的最小和最大宽高。

代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mixinResizable() {
  const positionParams = this.getPositionParams();

  // 计算最大宽度,不能超过窗口的宽度
  const maxWidth = calcGridItemPosition(
    positionParams,
    0,
    0,
    cols - x,
    0
  ).width;

  // 约束最大最小的宽度
  const mins = calcGridItemPosition(positionParams, 0, 0, minW, minH);
  const maxes = calcGridItemPosition(positionParams, 0, 0, maxW, maxH);
  // 计算可以缩放的最小宽高
  const minConstraints = [mins.width, mins.height];
  // 计算可以缩放的最大宽高
  const maxConstraints = [
    Math.min(maxes.width, maxWidth),
    Math.min(maxes.height, Infinity)
  ];
  
  return (
    <Resizable
      // 是否可缩放
      draggableOpts={{
        disabled: !isResizable
      }}
      className={isResizable ? undefined : "react-resizable-hide"}
      width={position.width}
      height={position.height}
      minConstraints={minConstraints}
      maxConstraints={maxConstraints}
      onResizeStop={this.onResizeStop}
      onResizeStart={this.onResizeStart}
      onResize={this.onResize}
      transformScale={transformScale}
      resizeHandles={resizeHandles}
      handle={resizeHandle}
    >
      {child}
    </Resizable>
  );
}

从上面的代码中我们还看到在 Resizable 组件中调用了一些拖拽事件例如:onResizeStart、onResizeStop、onResize 分别用于处理调整大小开始时、结束时、过程中触发的事件。都共同调用了 onResizeHandler 方法,下面我们来看下 onResizeHandler 函数:

onResizeHandler 函数用来更新组件的宽度和高度,调整组件的位置和边界,重新计算并更新布局,发送请求或触发其他副作用。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
onResizeHandler() {
  const handler = this.props[handlerName];
  if (!handler) return;
  const { cols, x, y, i, maxH, minH } = this.props;
  let { minW, maxW } = this.props;

  // 得到新的XY,给定像素值中的高度和宽度,计算网格单位。
  let { w, h } = calcWH(
    this.getPositionParams(),
    size.width,
    size.height,
    x,
    y
  );

  // minW应该至少是1 (TODO propTypes验证?)
  minW = Math.max(minW, 1);

  // maxW应该最多为(cols - x)
  maxW = Math.min(maxW, cols - x);

  // 最小/最大限制
  w = clamp(w, minW, maxW);
  h = clamp(h, minH, maxH);

  this.setState({ resizing: handlerName === "onResizeStop" ? null : size });

  handler.call(this, i, w, h, { e, node, size });
}

4. 总结

通过对 React-grid-layout 源码的学习,我们对它的使用也会更得心应手,这篇文章主要对组件元素的定位、拖拽、缩放功能的源码实现做了详细的介绍。在我们具体应用过程中还有很多值得我们深入思考的,例如通过对元素的拖拽实现吸附效果、拖拽的动画等等期待下一次的介绍!

5. 参考文献

https://github.com/react-grid-layout/react-grid-layout https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_grid_layout

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-10-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 政采云技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
本地化部署DeepSeek-R1蒸馏大模型:基于飞桨PaddleNLP 3.0的实战指南
在大模型时代的浪潮中,开源框架与推理优化的深度融合,正推动人工智能从“可用”走向“高效可部署”。飞桨(PaddlePaddle)作为国内领先的自主深度学习平台,在3.0版本中重构了模型开发与部署链路,面向大模型时代提供了更智能的编译调度、更高效的资源利用与更统一的训推体验。
鲲志说
2025/04/07
950
本地化部署DeepSeek-R1蒸馏大模型:基于飞桨PaddleNLP 3.0的实战指南
什么是DeepSeek-R1蒸馏模型?
DeepSeek在DeepSeek-V3之后发布了另一个革命性的模型,即DeepSeek-R1,这看起来是一个重大的发布,因为这个模型在几个基准测试中已经超越了OpenAI-o1,即SOTA推理模型。
码农编程进阶笔记
2025/04/26
990
什么是DeepSeek-R1蒸馏模型?
在Amazon Bedrock上部署DeepSeek-R1模型
在 Amazon Bedrock 部署 DeepSeek-R1 模型,解锁强大 AI 应用!本文详解如何将 Hugging Face 的 DeepSeek-R1 Distill Llama 模型导入 Bedrock,利用 AWS S3 存储,并通过 Bedrock API 调用。更有自动缩放、性能监控、API 安全等优化技巧,助力高效、安全地运行 LLM。
云云众生s
2025/03/16
1150
基于PaddleNLP使用DeepSeek-R1搭建智能体
最近在学习DeepSeek,找到了PaddleNLP星河社区大模型,跟着敲写了一遍。内容来源:DeepSeek实战训练营:从云端模型部署到应用开发 - 飞桨AI Studio星河社区-人工智能学习与实训社区
Harry技术
2025/03/10
1030
基于PaddleNLP使用DeepSeek-R1搭建智能体
DeepSeek 大模型基本认知(V3、R1、Janus、VL2 简单介绍以及本地部署)
“以开源精神和长期主义追求普惠 AGI” 是 DeepSeek 一直以来的坚定信念
山河已无恙
2025/02/25
1K0
DeepSeek 大模型基本认知(V3、R1、Janus、VL2 简单介绍以及本地部署)
【HuggingFace项目】:Open-R1 - DeepSeek-R1 大模型开源复现计划
Open-R1 是由 HuggingFace 发布的一个完全开放的项目,旨在通过三个主要步骤复现 DeepSeek-R1 的完整训练流程。这个项目的目标是让更多人能够理解和使用 DeepSeek-R1 的技术方案,从而推动大模型技术的发展和应用。
致Great
2025/01/27
4650
【HuggingFace项目】:Open-R1 - DeepSeek-R1 大模型开源复现计划
DeepSeek R1推理
DeepSeek R1和DeepSeek V3的模型结构一致,参数量也一致,R1是基于V3做强化学习得来的。R1主要的创新点都用在训练过程,推理过程和V3是一样的。
aaronwjzhao
2025/02/06
2.6K1
DeepSeek-R1大模型一键部署在腾讯云 TI 平台,告别卡顿
现在DeepSeek-R1大模型太火爆了,导致官网服务器压力太大,经常无法使用。由于DeepSeek-R1大模型是开源的,很多第三方平台已经支持部署DeepSeek-R1大模型。在这些平台上,可以建立独属于自己的DeepSeek-R1大模型服务,想怎么用就怎么用,再也不会卡顿。腾讯云 TI 平台目前已经支持DeepSeek-R1大模型,部署完成后体验很不错。
AIGC部落
2025/02/04
1.2K0
DeepSeek-R1大模型一键部署在腾讯云 TI 平台,告别卡顿
【大模型部署实战】VLLM+OpenWebUI实现DeepSeek模型部署,文末有福利
vLLM(Very Large Language Model Serving)是由加州大学伯克利分校团队开发的高性能、低延迟大语言模型(LLM)推理和服务框架。其核心创新在于PagedAttention技术,通过将注意力键值(KV)缓存分页管理,显著提升显存利用率并降低碎片化问题,使吞吐量比传统框架(如Hugging Face Transformers)提升24倍。该框架支持连续批处理、动态显存分配和多GPU并行推理,能够高效处理8k+长上下文请求,并兼容OpenAI API接口,开发者可快速部署Hugging Face模型。通过集成FP8、AWQ等量化技术,vLLM在保证推理精度的同时大幅降低资源消耗,目前已成为企业级AI部署(如DeepSeek-R1 671B模型分布式集群)的首选方案。
AI浩
2025/03/17
4220
【大模型部署实战】VLLM+OpenWebUI实现DeepSeek模型部署,文末有福利
DeepSeek-R1 高性能应用服务 HAI 开箱即用
一、环境说明 HAI已提供DeepSeek-R1 1.5B及7B模型预装环境(DeepSeek-R1-Distill-Qwen-1.5B、DeepSeek-R
geru
2025/01/31
12.5K5
一文看尽飞桨PaddlePaddle最新升级:5大优势,更低门槛使用深度学习
从Paddle Fluid v1.0以来,飞桨致力于打造更好的用户体验,趁着百度开发者大会,也为用户精心准备了一份大礼,在开发、训练及部署全流程上进行了全新升级,发布了飞桨的五大优势,接下来将一一解读。
量子位
2019/07/09
1.4K0
企业级模型推理部署工具vllm使用指南 - 部署最新deepseek-v3-0324模型
vLLM(Virtual Large Language Model)是由加州大学伯克利分校团队开发的高性能大模型推理框架,其核心特点围绕显存优化、高吞吐量、灵活性和易用性展开。
wayn
2025/04/09
4110
企业级模型推理部署工具vllm使用指南 - 部署最新deepseek-v3-0324模型
业界首发行业大模型,提出落地3大关键路径,百度的大模型原来是这么用的
机器之心报道 编辑:张倩 这次的 Wave Summit,我们聊聊大模型,但重点不是参数。 在过去的几年,深度学习领域掀起了一场轰轰烈烈的「练大模型」运动,千亿、万亿参数模型层出不穷。但与之形成反差的是,这些大模型的落地过程却非常缓慢。前段时间从谷歌离职创业的两位 Transformer 作者也感叹,虽然他们训练的模型越来越大,但这些模型却很难用来做实际的事情。 这个问题在国内同样引发了关注。在前段时间的百度认知 AI 创意赛决赛期间,百度集团副总裁、深度学习技术及应用国家工程研究中心副主任吴甜就提到,参数
机器之心
2022/05/23
1.4K0
业界首发行业大模型,提出落地3大关键路径,百度的大模型原来是这么用的
NLP涉及技术原理和应用简单讲解【一】:paddle(梯度裁剪、ONNX协议、动态图转静态图、推理部署)
https://www.paddlepaddle.org.cn/documentation/docs/zh/guides/advanced/gradient_clip_cn.html
汀丶人工智能
2022/12/21
1.2K0
NLP涉及技术原理和应用简单讲解【一】:paddle(梯度裁剪、ONNX协议、动态图转静态图、推理部署)
在 TKE 上使用 NVIDIA Dynamo 部署 PD 分离的大模型
刘瑾锋,腾讯云容器服务 TKE 后台开发工程师,主要负责容器服务(TKE)相关研发工作。
腾讯云原生
2025/04/21
4680
在 TKE 上使用 NVIDIA Dynamo 部署 PD 分离的大模型
在本地电脑部署自己的 DeepSeek 大模型 AI:小白也能轻松上手
最近 DeepSeek 大模型 AI 火遍全网,我也忍不住去了解了一番。尝试在本地部署后,发现整个过程非常简单,于是决定记录下来,分享给大家。本文将以最基础的方式演示如何部署,无需使用 Docker 容器,也不需要“魔法上网”,即使是计算机小白也能按照步骤轻松完成。
后端码匠
2025/02/06
3.1K0
【DeepSeek】在本地计算机上部署DeepSeek-R1大模型实战(完整版)
2025年1月,中国春节期间,DeepSeek爆火,称为全球最炙手可热的大模型。DeepSeek一路 “狂飙”,在美国科技界和美股市场掀起惊涛骇浪,1月27日,美国三大股指开盘即暴跌,英伟达、微软、谷歌母公司Alphabet、Meta等美国主要科技股均遭遇股市地震,其中英伟达跌近17%,单日市值蒸发约6000亿美元,创美股最高纪录。
Francek Chen
2025/02/12
1.4K0
【DeepSeek】在本地计算机上部署DeepSeek-R1大模型实战(完整版)
中医名词看不懂?用PaddleNLP做一个中医“百科全书”
我是一个深度学习爱好者,目前对自然语言处理感兴趣,热衷于了解一些人工智能中的数学推导和经典论文复现,正在成长的“小趴菜”一枚,在PPDE指导计划中,创作了中医文献阅读理解项目,下面将由我介绍在项目创作过程中的一些思考。
用户1386409
2023/03/06
4830
中医名词看不懂?用PaddleNLP做一个中医“百科全书”
使用Triton+TensorRT-LLM部署Deepseek模型
随着大模型项目的开源环境越来越好,大家在本地部署一个大语言模型跑demo应该是一件很简单的事情。但是要将模型运行到生产环境,就需要考虑模型运行性能,GPU资源的调度,高并发场景的支持等情况了。
languageX
2024/04/17
3.2K2
白话科普 | DeepSeek的蒸馏技术到底是什么?90%的人都没搞懂,但西方却抓着不放!
在人工智能领域,大型语言模型(LLM)无疑是近年来最耀眼的技术突破之一。然而,这些拥有数百亿甚至上千亿参数的庞然大物,虽然性能卓越,却也因其高昂的计算成本和资源需求而难以普及。如何让这些“巨无霸”级别的模型走进千家万户?答案就在于一种被称为知识蒸馏的技术。
AI研思录
2025/02/20
3700
白话科普 | DeepSeek的蒸馏技术到底是什么?90%的人都没搞懂,但西方却抓着不放!
推荐阅读
本地化部署DeepSeek-R1蒸馏大模型:基于飞桨PaddleNLP 3.0的实战指南
950
什么是DeepSeek-R1蒸馏模型?
990
在Amazon Bedrock上部署DeepSeek-R1模型
1150
基于PaddleNLP使用DeepSeek-R1搭建智能体
1030
DeepSeek 大模型基本认知(V3、R1、Janus、VL2 简单介绍以及本地部署)
1K0
【HuggingFace项目】:Open-R1 - DeepSeek-R1 大模型开源复现计划
4650
DeepSeek R1推理
2.6K1
DeepSeek-R1大模型一键部署在腾讯云 TI 平台,告别卡顿
1.2K0
【大模型部署实战】VLLM+OpenWebUI实现DeepSeek模型部署,文末有福利
4220
DeepSeek-R1 高性能应用服务 HAI 开箱即用
12.5K5
一文看尽飞桨PaddlePaddle最新升级:5大优势,更低门槛使用深度学习
1.4K0
企业级模型推理部署工具vllm使用指南 - 部署最新deepseek-v3-0324模型
4110
业界首发行业大模型,提出落地3大关键路径,百度的大模型原来是这么用的
1.4K0
NLP涉及技术原理和应用简单讲解【一】:paddle(梯度裁剪、ONNX协议、动态图转静态图、推理部署)
1.2K0
在 TKE 上使用 NVIDIA Dynamo 部署 PD 分离的大模型
4680
在本地电脑部署自己的 DeepSeek 大模型 AI:小白也能轻松上手
3.1K0
【DeepSeek】在本地计算机上部署DeepSeek-R1大模型实战(完整版)
1.4K0
中医名词看不懂?用PaddleNLP做一个中医“百科全书”
4830
使用Triton+TensorRT-LLM部署Deepseek模型
3.2K2
白话科普 | DeepSeek的蒸馏技术到底是什么?90%的人都没搞懂,但西方却抓着不放!
3700
相关推荐
本地化部署DeepSeek-R1蒸馏大模型:基于飞桨PaddleNLP 3.0的实战指南
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验